{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 代码参考来源：https://github.com/nathanhubens/Autoencoders"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 利用手写体数据集实现四种自编码器：\n",
    "1.单层自编码器   \n",
    "2.多层自编码器  \n",
    "3.卷积自编码器    \n",
    "4.正则自编码器  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 145,
   "metadata": {},
   "outputs": [],
   "source": [
    "import keras\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from keras.datasets import mnist\n",
    "from keras.models import Model\n",
    "from keras.layers import Input, add\n",
    "from keras.layers.core import Layer, Dense, Dropout, Activation, Flatten, Reshape\n",
    "from keras import regularizers\n",
    "from keras.regularizers import l2\n",
    "from keras.layers.convolutional import Conv2D, MaxPooling2D, UpSampling2D, ZeroPadding2D\n",
    "from keras.utils import np_utils"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***\n",
    "# 1.单层自编码器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 读取手写体数据及与图像预处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 146,
   "metadata": {},
   "outputs": [],
   "source": [
    "(X_train, _), (X_test, _) = mnist.load_data()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 147,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "X_train shape: (60000, 28, 28)\n",
      "60000 train samples\n",
      "10000 test samples\n"
     ]
    }
   ],
   "source": [
    "\n",
    "#  归一化\n",
    "X_train = X_train.astype(\"float32\")/255.\n",
    "X_test = X_test.astype(\"float32\")/255.\n",
    "\n",
    "print('X_train shape:', X_train.shape)\n",
    "print(X_train.shape[0], 'train samples')\n",
    "print(X_test.shape[0], 'test samples')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### np.prod是将28X28矩阵转化成1X784，方便BP神经网络输入层784个神经元读取。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 148,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train = X_train.reshape((len(X_train), np.prod(X_train.shape[1:])))\n",
    "X_test = X_test.reshape((len(X_test), np.prod(X_test.shape[1:])))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 构建自编码器模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 149,
   "metadata": {},
   "outputs": [],
   "source": [
    "input_size = 784\n",
    "hidden_size = 64\n",
    "output_size = 784"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 150,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = Input(shape=(input_size,))\n",
    "h = Dense(hidden_size, activation='relu')(x)\n",
    "r = Dense(output_size, activation='sigmoid')(h)\n",
    "\n",
    "autoencoder = Model(inputs=x, outputs=r)\n",
    "autoencoder.compile(optimizer='adam', loss='mse')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 模型可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 151,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<svg height=\"191pt\" viewBox=\"0.00 0.00 177.00 191.00\" width=\"177pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g class=\"graph\" id=\"graph0\" transform=\"scale(1 1) rotate(0) translate(4 187)\">\n",
       "<title>G</title>\n",
       "<polygon fill=\"white\" points=\"-4,4 -4,-187 173,-187 173,4 -4,4\" stroke=\"none\"/>\n",
       "<!-- 140641035006248 -->\n",
       "<g class=\"node\" id=\"node1\"><title>140641035006248</title>\n",
       "<polygon fill=\"none\" points=\"-1.42109e-14,-146.5 -1.42109e-14,-182.5 169,-182.5 169,-146.5 -1.42109e-14,-146.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"84.5\" y=\"-160.8\">input_28: InputLayer</text>\n",
       "</g>\n",
       "<!-- 140641035007536 -->\n",
       "<g class=\"node\" id=\"node2\"><title>140641035007536</title>\n",
       "<polygon fill=\"none\" points=\"16,-73.5 16,-109.5 153,-109.5 153,-73.5 16,-73.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"84.5\" y=\"-87.8\">dense_50: Dense</text>\n",
       "</g>\n",
       "<!-- 140641035006248&#45;&gt;140641035007536 -->\n",
       "<g class=\"edge\" id=\"edge1\"><title>140641035006248-&gt;140641035007536</title>\n",
       "<path d=\"M84.5,-146.313C84.5,-138.289 84.5,-128.547 84.5,-119.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"88.0001,-119.529 84.5,-109.529 81.0001,-119.529 88.0001,-119.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641035006360 -->\n",
       "<g class=\"node\" id=\"node3\"><title>140641035006360</title>\n",
       "<polygon fill=\"none\" points=\"16,-0.5 16,-36.5 153,-36.5 153,-0.5 16,-0.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"84.5\" y=\"-14.8\">dense_51: Dense</text>\n",
       "</g>\n",
       "<!-- 140641035007536&#45;&gt;140641035006360 -->\n",
       "<g class=\"edge\" id=\"edge2\"><title>140641035007536-&gt;140641035006360</title>\n",
       "<path d=\"M84.5,-73.3129C84.5,-65.2895 84.5,-55.5475 84.5,-46.5691\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"88.0001,-46.5288 84.5,-36.5288 81.0001,-46.5289 88.0001,-46.5288\" stroke=\"black\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>"
      ],
      "text/plain": [
       "<IPython.core.display.SVG object>"
      ]
     },
     "execution_count": 151,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from IPython.display import SVG\n",
    "from keras.utils.vis_utils import model_to_dot\n",
    "\n",
    "SVG(model_to_dot(autoencoder).create(prog='dot', format='svg'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 152,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 60000 samples, validate on 10000 samples\n",
      "Epoch 1/5\n",
      "60000/60000 [==============================] - 4s 61us/step - loss: 0.0446 - val_loss: 0.0224\n",
      "Epoch 2/5\n",
      "60000/60000 [==============================] - 2s 38us/step - loss: 0.0174 - val_loss: 0.0130\n",
      "Epoch 3/5\n",
      "60000/60000 [==============================] - 2s 39us/step - loss: 0.0110 - val_loss: 0.0089\n",
      "Epoch 4/5\n",
      "60000/60000 [==============================] - 2s 39us/step - loss: 0.0080 - val_loss: 0.0067\n",
      "Epoch 5/5\n",
      "60000/60000 [==============================] - 2s 39us/step - loss: 0.0064 - val_loss: 0.0056\n"
     ]
    }
   ],
   "source": [
    "\n",
    "epochs = 5\n",
    "batch_size = 128\n",
    "\n",
    "history = autoencoder.fit(X_train, X_train, \n",
    "                          batch_size=batch_size, \n",
    "                          epochs=epochs, verbose=1, \n",
    "                          validation_data=(X_test, X_test)\n",
    "                         )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  查看自编码器的压缩效果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 153,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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AIAKGHEAAAAAKtDUn4Pb2tri0EMPzTqXePXVV9PaEydOTGtHRIwfPz6tPWXKlGKt7u7ueOaZZ4r1Go0bNy6tvWjRorR2RMQ999yT2v/xj39crNXW1hb7779/sV6jO+64I629cePGtHZExGmnnZbWHjRoULHWNttsE6NGjSrWe71+lqeffjqtHRExadKk1P4f//jHYq3W1tbYb7/9ivUalTzXRldeeWVaOyL3M/2Xv/xlsVZ7e3scccQRxXqNZs2aldbu6elJa0dEnHTSSan9adOmFWuNGzcufvaznxXrNTruuOPS2pnfISNyv5sNHjy4WKu7uzv++te/Fus1Gjt2bFo7834XEXH88cen9h988MFireHDh8f73//+Yr1G8+fPT2tv2LAhrR0RccUVV6S1582bV6w1cuTIOO+884r1Gt1///1p7eeeey6tHRHxkY98JLW/tb/TPYkDAAAAUAEjDgAAAEAFjDgAAAAAFTDiAAAAAFTAiAMAAABQASMOAAAAQAWMOAAAAAAVMOIAAAAAVMCIAwAAAFABIw4AAABABYw4AAAAABUw4gAAAABUwIgDAAAAUAEjDgAAAEAFjDgAAAAAFTDiAAAAAFTAiAMAAABQASMOAAAAQAWMOAAAAAAVMOIAAAAAVMCIAwAAAFABIw4AAABABYw4AAAAABVo6s/BI0aMiOOPPz7rXOKJJ55Ia++yyy5p7YiIT3/606n9UtatWxePPPJIWn+33XZLax9zzDFp7YiIT3ziE6n9krq7u+PZZ59N67/pTW9Ka59//vlp7YiIG264Ia29evXqYq2BAwdGa2trsV6jPfbYI639wgsvpLUjIl588cXUfkkDBw6M5ubmtH53d3dae/LkyWntiIjPfOYzae3FixcXa23cuDGWLFlSrNeot7c3rX3xxRentSMibrvtttR+SQsXLoxTTz01rT9hwoS09t57753Wjsh9nyxdurRYq6+vL3p6eor1GmV+Rz355JPT2hERN998c2q/pN7e3qLvi0bz5s1La7/rXe9Ka0dEnH766WntRYsWFWtl/148++yz09qdnZ1p7YiIb3zjG6n9reVJHAAAAIAKGHEAAAAAKmDEAQAAAKiAEQcAAACgAkYcAAAAgAoYcQAAAAAqYMQBAAAAqIARBwAAAKACRhwAAACAChhxAAAAACpgxAEAAACogBEHAAAAoAJG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\n",
      "text/plain": [
       "<Figure size 1440x576 with 10 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "conv_encoder = Model(x, h)  # 只取编码器做模型\n",
    "encoded_imgs = conv_encoder.predict(X_test)\n",
    "\n",
    "# 打印10张测试集手写体的压缩效果\n",
    "n = 10\n",
    "plt.figure(figsize=(20, 8))\n",
    "for i in range(n):\n",
    "    ax = plt.subplot(1, n, i+1)\n",
    "    plt.imshow(encoded_imgs[i].reshape(4, 16).T)\n",
    "    plt.gray()\n",
    "    ax.get_xaxis().set_visible(False)\n",
    "    ax.get_yaxis().set_visible(False)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 查看自编码器的解码效果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 154,
   "metadata": {},
   "outputs": [],
   "source": [
    "decoded_imgs = autoencoder.predict(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 155,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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tfXbNL3miiuusLhly5ZRv6zxctVVV0Xbmh5eyj0v8vGpM5oapSkxo0aNivp99tlnFi9ZssRif53S+9Knn346aps4caLFr732msWvv/561G/FihWZr4/8dPmFEOIxpvea/juR1w477GDxl19+GbW98847Fo8ePTpq0+/c559/XtJ7l4KZOAAAAAAAAAXAQxwAAAAAAIAC4CEOAAAAAABAAdTrmjhaUjyEELbZZhuLJ0+eHLVtueWWFqfyknfccUeL33//fYuzSgJWR/PgFixYYLGWz/ZmzZoVbTfWNXGUrn9RqtNOO83izTffPLOf5qJWt42G6/TTT7fYf2cYR+UxcuRIi7UEeKm0lOqyZcuitg4dOlisZW7Hjh0b9VtllVW+835UOp8PrmWip02bZvGf//znOtun/fffv87eC9/WtWvXaLt79+6ZffXe5sknnyzbPlWKNm3aRNsHH3xwZt9f/epXFut9Y7npOjj/+Mc/Mvv5NXH8epII4be//a3FWjI+L7/O21577WWxL1Ou6+fU5RoalSK1Ts22225rsZaW9saMGWOx/l05Y8aMqF/79u0t1rVQQ6iddQTxbfo8YMiQIRb7MbbuuutW+/Nz5syJtl966SWL33vvvahN/wbRtRl79eoV9dNzwj777BO1TZgwwWItU15uzMQBAAAAAAAoAB7iAAAAAAAAFEC9plM9++yzyW3lS8N9w5c37datm8U6Lapnz5659+vTTz+1+N1337XYp3jp1Cqdyo7vpn///hZrqc7vf//7Ub/58+dbfOaZZ0Ztn3zySZn2Dt9Vx44do+0ePXpYrOMtBEox1pbdd9892t5iiy0s1unAeacG++miOp1ZS3WGEMKee+5pcar88f/7f//P4uuuuy7XfjQ2Z599drStU8p16r5Paatteu3z3y2ml9etVIqP59MOkPbXv/412j788MMt1vvLEEK4//7762SfvN69e1vctm3bqO3WW2+1+I477qirXSoMTfUNIYTBgwdX2+/NN9+MtufNm2dx3759M1+/WbNmFmuqVggh3HnnnRbPnTt35TvbyPn7/7vuustiTZ8KIU4nTqUYKp9CpfxyGah9N9xwQ7StaXCpcuH63OCtt96y+Kyzzor66d/13s4772yx3ofefPPNUT99vqDngBBCuOaaayx+4IEHLC53ai0zcQAAAAAAAAqAhzgAAAAAAAAFUK/pVLVh8eLF0fZzzz1Xbb9UqlaKTlX2qVs6devee+8t6fXxbZpe46dQKv3MX3jhhbLuE2qPT79QdVnVo9Jp2to999wTtaWmpyqtFqZTRP/4xz9G/VLpi/oaxxxzjMWtW7eO+l1yySUWr7HGGlHb1VdfbfEXX3yxst2uKAMHDrTYV0SYOnWqxXVZyU3T4nz61PPPP2/xxx9/XFe71GjttttumW2+6k0qnRHfVlVVFW3rd/2DDz6I2spZYWjNNdeMtjVV4Ne//rXFfn+PPPLIsu1TJdD0iBBCWGeddSzWajb+nkWvTz/72c8s9ikcnTp1snj99deP2h555BGL9957b4sXLVqUa98bg6ZNm1rsl0zQZRcWLlwYtV166aUWs7RCw+Hv67Qq1FFHHRW1NWnSxGL9u8Cn2g8dOtTiUpdfaNmypcVaJfW8886L+umyLj4Vs74wEwcAAAAAAKAAeIgDAAAAAABQADzEAQAAAAAAKIDCr4lTDm3atLH42muvtfh734ufeWn5a/JYS/fwww9H2z/+8Y+r7Xf77bdH277cLoqha9eumW26Lgq+m1VX/d/pPe8aOH5tqUMPPdRin3eel66Jc9FFF1l82WWXRf3WWmsti/334NFHH7V42rRpJe1HUR1yyCEW62cUQnx9KjddY2nQoEEWf/XVV1G/Cy+80OLGtn5RXdGSqBp7fo2AN954o2z71Njsu+++0baWb9e1oPwaDnnpOix77LFH1LbjjjtW+zMjRowo6b0aq9VXXz3a1jWFLr/88syf03LFt9xyi8V6rg4hhE033TTzNXStlnKup1RkBxxwgMW/+93vojYt+927d++obcmSJeXdMZTEn8dOO+00i3UNnBBCmDNnjsW6Nu3YsWNLem9d66Zdu3ZRm/5tOXLkSIv9OrjK7+/w4cMtrsu1AJmJAwAAAAAAUAA8xAEAAAAAACgA0qmqMWTIEIu1DK4vZ/7OO+/U2T5Vmg022MBiPx1cp7hqCodO0w8hhGXLlpVp71DbdPr34MGDo7bXX3/d4meeeabO9gn/R0tT+5K0paZQZdG0KE3JCSGEnj171up7FVWzZs2i7azUiRBKT9UohZaH1/S8yZMnR/2ee+65OtunxirvWKnL70clGjZsWLTdp08fizfccMOoTUu961T7/fbbr6T31tfwpcPV9OnTLfYlrpGm5cE9TZfzKf9ZevTokfu9x4wZYzH3stVLpYrqfePs2bPrYnfwHWlKUwjfTsVWX375pcU77LCDxQMHDoz6/eAHP6j251esWBFtb7nlltXGIcT3uW3bts3cJzVv3rxou77SyJmJAwAAAAAAUAA8xAEAAAAAACgA0qlCCLvssku07VdB/4aulB5CCBMnTizbPlW6Bx54wOKWLVtm9rvjjjssbmxVaSpJ3759LW7RokXUNmrUKIu16gNqj6+sp3SqarlpioDfp9Q+nnfeeRb//Oc/r/X9akh8xZSNNtrI4rvvvruud8d06tSp2n/nOlj3UmkbtVEZCf9n/Pjx0fY222xjcbdu3aK2vfbay2KturJgwYKo32233ZbrvbXayYQJEzL7vfLKKxZzj1Qz/nyqqW+asuhTNrTC5oEHHmixr2ajY9G3HX300RbrsZ40aVKufW8MfOqM0vF27rnnRm2PPPKIxVTkazj++c9/Rtuaeq1/I4QQQvv27S2+8sorLU6llmp6lk/dSslKofr666+j7Yceesji3/zmN1Hbhx9+mPv9ahMzcQAAAAAAAAqAhzgAAAAAAAAFwEMcAAAAAACAAmBNnBDCPvvsE22vttpqFj/77LMWv/rqq3W2T5VI84233377zH7PP/+8xT7XFcW07bbbWuxzWkeMGFHXu9MoHHfccRb73N76MmDAAIu32267qE330e+vrolT6f773/9G25rTr2tyhBCvL7Vo0aJa3Y82bdpE21nrE4wePbpW3xfV23XXXS0+7LDDMvstWbLEYkrv1q7FixdbrOs5+O0zzjjjO7/XpptuarGuJRZCfE747W9/+53fq7H6xz/+EW3r2NF1b/w6NVnrcvjXGzJkiMWPP/541LbZZptZrOtr6HW7sWvdurXF/p5A144755xzorazzz7b4uuvv95iLeseQrzuytSpUy1+++23M/dp6623jrb170LOt2m+7LeuJ9W8efOoTdem1XVrP/roo6jfrFmzLNbvhP7NEUIIvXr1qvH+3njjjdH2WWedZbGud1WfmIkDAAAAAABQADzEAQAAAAAAKIBGm0615pprWqyl6kII4fPPP7dY03m++OKL8u9YBfGlw3UqmqaseTpVeNmyZbW/Y6gT66+/vsW9e/e2+J133on6adk+1B5NXapLOgU6hBC22mori/UckOLL8jamc6+fcqxlgw8++OCo7Ykn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\n",
      "text/plain": [
       "<Figure size 1440x432 with 20 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "n = 10\n",
    "plt.figure(figsize=(20, 6))\n",
    "for i in range(n):\n",
    "    # 打印原图\n",
    "    ax = plt.subplot(3, n, i+1)\n",
    "    plt.imshow(X_test[i].reshape(28, 28))\n",
    "    plt.gray()\n",
    "    ax.get_xaxis().set_visible(False)\n",
    "    ax.get_yaxis().set_visible(False)\n",
    "\n",
    "    \n",
    "    # 打印解码图\n",
    "    ax = plt.subplot(3, n, i+n+1)\n",
    "    plt.imshow(decoded_imgs[i].reshape(28, 28))\n",
    "    plt.gray()\n",
    "    ax.get_xaxis().set_visible(False)\n",
    "    ax.get_yaxis().set_visible(False)\n",
    "    \n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练过程可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 156,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dict_keys(['val_loss', 'loss'])\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "print(history.history.keys())\n",
    "\n",
    "plt.plot(history.history['loss'])\n",
    "plt.plot(history.history['val_loss'])\n",
    "plt.title('model loss')\n",
    "plt.ylabel('loss')\n",
    "plt.xlabel('epoch')\n",
    "plt.legend(['train', 'validation'], loc='upper right')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***\n",
    "# 2.多层自编码器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 多层自编码器建模"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 157,
   "metadata": {},
   "outputs": [],
   "source": [
    "input_size = 784\n",
    "hidden_size = 128\n",
    "code_size = 64\n",
    "\n",
    "x = Input(shape=(input_size,))\n",
    "hidden_1 = Dense(hidden_size, activation='relu')(x)\n",
    "h = Dense(code_size, activation='relu')(hidden_1)\n",
    "hidden_2 = Dense(hidden_size, activation='relu')(h)\n",
    "r = Dense(input_size, activation='sigmoid')(hidden_2)\n",
    "\n",
    "autoencoder = Model(inputs=x, outputs=r)\n",
    "autoencoder.compile(optimizer='adam', loss='mse')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 模型可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 158,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<svg height=\"337pt\" viewBox=\"0.00 0.00 177.00 337.00\" width=\"177pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g class=\"graph\" id=\"graph0\" transform=\"scale(1 1) rotate(0) translate(4 333)\">\n",
       "<title>G</title>\n",
       "<polygon fill=\"white\" points=\"-4,4 -4,-333 173,-333 173,4 -4,4\" stroke=\"none\"/>\n",
       "<!-- 140641044769256 -->\n",
       "<g class=\"node\" id=\"node1\"><title>140641044769256</title>\n",
       "<polygon fill=\"none\" points=\"-1.42109e-14,-292.5 -1.42109e-14,-328.5 169,-328.5 169,-292.5 -1.42109e-14,-292.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"84.5\" y=\"-306.8\">input_29: InputLayer</text>\n",
       "</g>\n",
       "<!-- 140641044768920 -->\n",
       "<g class=\"node\" id=\"node2\"><title>140641044768920</title>\n",
       "<polygon fill=\"none\" points=\"16,-219.5 16,-255.5 153,-255.5 153,-219.5 16,-219.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"84.5\" y=\"-233.8\">dense_52: Dense</text>\n",
       "</g>\n",
       "<!-- 140641044769256&#45;&gt;140641044768920 -->\n",
       "<g class=\"edge\" id=\"edge1\"><title>140641044769256-&gt;140641044768920</title>\n",
       "<path d=\"M84.5,-292.313C84.5,-284.289 84.5,-274.547 84.5,-265.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"88.0001,-265.529 84.5,-255.529 81.0001,-265.529 88.0001,-265.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641034910968 -->\n",
       "<g class=\"node\" id=\"node3\"><title>140641034910968</title>\n",
       "<polygon fill=\"none\" points=\"16,-146.5 16,-182.5 153,-182.5 153,-146.5 16,-146.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"84.5\" y=\"-160.8\">dense_53: Dense</text>\n",
       "</g>\n",
       "<!-- 140641044768920&#45;&gt;140641034910968 -->\n",
       "<g class=\"edge\" id=\"edge2\"><title>140641044768920-&gt;140641034910968</title>\n",
       "<path d=\"M84.5,-219.313C84.5,-211.289 84.5,-201.547 84.5,-192.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"88.0001,-192.529 84.5,-182.529 81.0001,-192.529 88.0001,-192.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641044709672 -->\n",
       "<g class=\"node\" id=\"node4\"><title>140641044709672</title>\n",
       "<polygon fill=\"none\" points=\"16,-73.5 16,-109.5 153,-109.5 153,-73.5 16,-73.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"84.5\" y=\"-87.8\">dense_54: Dense</text>\n",
       "</g>\n",
       "<!-- 140641034910968&#45;&gt;140641044709672 -->\n",
       "<g class=\"edge\" id=\"edge3\"><title>140641034910968-&gt;140641044709672</title>\n",
       "<path d=\"M84.5,-146.313C84.5,-138.289 84.5,-128.547 84.5,-119.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"88.0001,-119.529 84.5,-109.529 81.0001,-119.529 88.0001,-119.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641035006584 -->\n",
       "<g class=\"node\" id=\"node5\"><title>140641035006584</title>\n",
       "<polygon fill=\"none\" points=\"16,-0.5 16,-36.5 153,-36.5 153,-0.5 16,-0.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"84.5\" y=\"-14.8\">dense_55: Dense</text>\n",
       "</g>\n",
       "<!-- 140641044709672&#45;&gt;140641035006584 -->\n",
       "<g class=\"edge\" id=\"edge4\"><title>140641044709672-&gt;140641035006584</title>\n",
       "<path d=\"M84.5,-73.3129C84.5,-65.2895 84.5,-55.5475 84.5,-46.5691\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"88.0001,-46.5288 84.5,-36.5288 81.0001,-46.5289 88.0001,-46.5288\" stroke=\"black\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>"
      ],
      "text/plain": [
       "<IPython.core.display.SVG object>"
      ]
     },
     "execution_count": 158,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from IPython.display import SVG\n",
    "from keras.utils.vis_utils import model_to_dot\n",
    "\n",
    "SVG(model_to_dot(autoencoder).create(prog='dot', format='svg'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 159,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 60000 samples, validate on 10000 samples\n",
      "Epoch 1/5\n",
      "60000/60000 [==============================] - 6s 93us/step - loss: 0.0410 - val_loss: 0.0196\n",
      "Epoch 2/5\n",
      "60000/60000 [==============================] - 4s 64us/step - loss: 0.0162 - val_loss: 0.0133\n",
      "Epoch 3/5\n",
      "60000/60000 [==============================] - 4s 64us/step - loss: 0.0119 - val_loss: 0.0103\n",
      "Epoch 4/5\n",
      "60000/60000 [==============================] - 4s 63us/step - loss: 0.0099 - val_loss: 0.0088\n",
      "Epoch 5/5\n",
      "60000/60000 [==============================] - 4s 63us/step - loss: 0.0087 - val_loss: 0.0081\n"
     ]
    }
   ],
   "source": [
    "epochs = 5\n",
    "batch_size = 128\n",
    "\n",
    "history = autoencoder.fit(X_train, X_train, \n",
    "                          batch_size=batch_size, \n",
    "                          epochs=epochs, \n",
    "                          verbose=1, \n",
    "                          validation_data=(X_test, X_test)\n",
    "                         )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 查看编码效果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 160,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABHEAAAGPCAYAAADbSEyPAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAHyZJREFUeJzt23uM3XW57/FnepEy09J7C1W2g1wrchNFMF4CUpAgahFEQFCkCkgqGsFSvICYikYRQUEEDAoGRQooUFAUhCi2KkSkXJQSoUClFWlLKx2mQNf545yTnCzZZ0/N9wn7cb9ef//yzo/1m++sNR9WezqdTgAAAADw39uwl/oGAAAAAPivGXEAAAAACjDiAAAAABRgxAEAAAAowIgDAAAAUIARBwAAAKAAIw4AAABAAUYcAAAAgAKMOAAAAAAFjNiYi8eMGdOZPHly1r3Ehg0b0tqdTietHRHx6KOPpvY7nU5Pi87o0aM748ePb5F6Uc8++2xae9SoUWntiIjHH388tR8Rf+90Ok0O0JgxYzoTJ05skXpRm2yySVo724MPPpjab3UWN9tss87UqVNbpF7U6tWr09qZv6sjIlauXJnaj4ZncfTo0Z0JEya0SL2ogYGBtPaIERv1EWCjLV++PLVf5SyOHTs2rf3000+ntSMiHnroodR+NDyLvb29nczXOtNzzz2X2n/qqadS+63O4siRIzuZn/WmTZuW1l61alVaOyLiySefTO1Hw7M4adKkTn9/f4vUi/rb3/6W1s7+fLNs2bLUfsu/FzP/zujr60trZ/58ROT/Po0hnsWN+gQ3efLkOPPMM//1W/ovZL6JZb9BHnfccan9VsaPHx+f/OQn0/r33ntvWnuHHXZIa0dEnHLKKan9iFjaKjRx4sT4zGc+0yr3T171qleltYcNy/0C4N57753ab2Xq1Knxta99La1/ww03pLXXrl2b1o6I+MEPfpDaj4ZnccKECam/UxcvXpzWnjJlSlo7IuKss85K7beSfRYPOuigtHbmOY/Ivff/o9lZHDt2bBxzzDGtcv8k838GrlixIq0dEXHppZem9lsZNWpUvO51r0vrf+5zn0tr/+hHP0prR0RceOGFqf1oeBb7+/vjzjvvbJX7J+eee25ae926dWntiIjTTjsttd/KxIkTY+7cuWn9PfbYI6193nnnpbUjIr73ve+l9mOIZ9E/pwIAAAAowIgDAAAAUIARBwAAAKAAIw4AAABAAUYcAAAAgAKMOAAAAAAFGHEAAAAACjDiAAAAABRgxAEAAAAowIgDAAAAUIARBwAAAKAAIw4AAABAAUYcAAAAgAKMOAAAAAAFGHEAAAAACjDiAAAAABRgxAEAAAAowIgDAAAAUIARBwAAAKAAIw4AAABAAUYcAAAAgAJGbMzFg4OD8eijj2bdS0yfPj2tfeWVV6a1IyJuuummtPbHPvaxZq2nnnoqvvvd7zbrddthhx3S2lOmTElrR0ScccYZZfqDg4Pxl7/8pVmv2+abb57WPuyww9LaEREPPfRQWvvd7353s9bq1avj+uuvb9brtmrVqrT2oYcemtaOiFizZk1qf8GCBc1aPT09semmmzbrdVu5cmVae999901rR0Tst99+ae1FixY1az3zzDNx5513Nut122yzzdLaxx13XFo7ImLhwoWp/b322qtZq7e3N1772tc263UbN25cWvu2225La0dEnHzyyWntyy+/vFlrYGAg/vCHPzTrdfvUpz6V1m75OryY7LO+2267NWv96U9/anq2u2211VZp7alTp6a1IyJOP/30tPZFF13UrDV8+PAYO3Zss163xYsXp7XHjBmT1o6IeOCBB1L7Q91DfBMHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQgBEHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQgBEHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFDBiYy7udDrx7LPPZt1LLFmyJK195ZVXprUjIiZMmJDWXr16dbPWtGnT4owzzmjW63bzzTentT/wgQ+ktSMidtxxx9R+S5tttlnMmDEjrf+Nb3wjrb1u3bq0dkTEqaeemtZetmxZs9awYcNi9OjRzXrdpkyZktY+7LDD0toREZdffnlqf8GCBc1aq1atih/+8IfNet122WWXtPbhhx+e1o6IOOSQQ9Law4cPb9bq7e1NfZ1vu+22tPZf//rXtHZExKJFi1L7LW2yySbR39+f1v/Sl76U1r766qvT2hERX//619PaL3vZy5q1ttpqqzj33HOb9br95Cc/SWtPnz49rR0Rccopp6T2W+rr64s99tgjrT958uS09mc/+9m0dkTE+973vrR2y7/RN2zYEAMDA8163e6+++609je/+c20dkTEzjvvnNofKt/EAQAAACjAiAMAAABQgBEHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQgBEHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQgBEHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKGLExF48cOTKmTZuWdS/x/PPPp7Xf8pa3pLUjIlatWpXWbvm6/O1vf4vzzjuvWa/bjBkz0tqdTietHRHx/ve/P7V/3333NWuNGTMm9t5772a9bk899VRae86cOWntiIg77rgjrb1o0aJmrfXr18cjjzzSrNdt9uzZae2VK1emtSMi7rrrrtR+S+PGjYt3vetdaf0VK1aktTPfCyIixo8fn9Zu+TPS19cXe+65Z7Net0033TStvXjx4rR2RMT8+fNT+y0tW7YsPv3pT6f199lnn7T2CSeckNaOiFi4cGFa+4UXXmjWevjhh+Poo49u1uv28Y9/PK09b968tHZExEEHHZTa/8pXvtK0N3z48Ka9/9ewYXnfQbj11lvT2hERDz30UFq75TkfGBiIe++9t1mv28yZM9Pav/rVr9LaERH33HNPan+ofBMHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQgBEHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQgBEHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAAChgxMZc/OSTT8a3v/3trHuJu+++O6196qmnprUjIn7/+9+ntZ9//vlmrREjRsSUKVOa9bqddtppae0HH3wwrR0RMW3atNR+S0uWLIkDDjggrf/Tn/40rX3SSSeltSPanpdug4ODzVrr16+PZcuWNet122effdLa++23X1o7ImKnnXZK7be0atWquPbaa9P6t99+e1r76KOPTmtHRDz77LNp7dWrVzdrLV26NI477rhmvW433HBDWvuYY45Ja0dE7Lrrrqn9lgYGBuK+++5L6998881p7dNPPz2tHRGxZs2atHbL99wtt9wy9bXIPC/ZZ+X+++9P7be0evXquOaaa9L6S5cuTWvPnDkzrR0RMXny5LT2M88806y1du3auOWWW5r1up1zzjlp7ezfp6NGjUrtD5Vv4gAAAAAUYMQBAAAAKMCIAwAAAFCAEQcAAACgACMOAAAAQAFGHAAAAIACjDgAAAAABRhxAAAAAAow4gAAAAAUYMQBAAAAKMCIAwAAAFCAEQcAAACgACMOAAAAQAFGHAAAAIACjDgAAAAABRhxAAAAAAow4gAAAAAUYMQBAAAAKMCIAwAAAFCAEQcAAACgACMOAAAAQAFGHAAAAIACRmzMxX19ffH6178+615i9erVae21a9emtSMi3vGOd6S1//znPzdrdTqdGBwcbNbrtscee6S1H3nkkbR2RMQWW2yR2m9p9OjRsddee6X13/ve96a1H3/88bR2RER/f39ae8GCBc1aPT090dPT06zXbbvttktr77nnnmntiIiRI0em9lt6+ctfHl/4whfS+i1/5rp96UtfSmtH5L4vbtiwoVlr3LhxMXPmzGa9bpnvi2PGjElrR0Rsu+22qf2Wxo0bF+985zvT+n/4wx/S2pMmTUprR0SsW7curd3yfWzDhg0xMDDQrNct87PNmWeemdaOiJg3b15qv6VJkybFsccem9ZfuHBhWnv//fdPa0dEXHLJJWntlud8woQJcfjhhzfrdWv5Ht7t7rvvTmtH5P6dsTF8EwcAAACgACMOAAAAQAFGHAAAAIACjDgAAAAABRhxAAAAAAow4gAAAAAUYMQBAAAAKMCIAwAAAFCAEQcAAACgACMOAAAAQAFGHAAAAIACjDgAAAAABRhxAAAAAAow4gAAAAAUYMQBAAAAKMCIAwAAAFCAEQcAAACgACMOAAAAQAFGHAAAAIACjDgAAAAABRhxAAAAAAow4gAAAAAUYMQBAAAAKKCn0+kM/eKenqFf/C9461vfmtY+55xz0toREd/4xjfS2tddd138/e9/72nRyn6Gs2fPTmvvuuuuae2IiJ6eJi/xf+pDH/rQXZ1O53UtWtnP8Re/+EVa+8EHH0xrR0Q89thjae1LL700nnjiiRJn8ZOf/GRaO/ss9vb2pvbf8573lDmL73vf+9LaO+ywQ1o7ImL33XdPa3/iE5+IJUuWlDiLv/3tb9Pa119/fVo7ImLVqlWp/fPPP7/MWbz00kvT2nfddVdaOyJixYoVae1f/OIXsXLlyhJn8ctf/nJaO/t9Mfuz0+zZs8ucxf322y+tvd1226W1IyJGjRqV1r788stj+fLlJc7iF7/4xbT2+vXr09oREVOmTEntf/SjHx3SWfRNHAAAAIACjDgAAAAABRhxAAAAAAow4gAAAAAUYMQBAAAAKMCIAwAAAFCAEQcAAACgACMOAAAAQAFGHAAAAIACjDgAAAAABRhxAAAAAAow4gAAAAAUYMQBAAAAKMCIAwAAAFCAEQcAAACgACMOAAAAQAFGHAAAAIACjDgAAAAABRhxAAAAAAow4gAAAAAUYMQBAAAAKMCIAwAAAFCAEQcAAACggBEbc/FWW20VZ555Zta9xIc//OG09imnnJLWjojYsGFDWnv9+vXNWlOmTIkjjzyyWa/bpEmT0tp33nlnWjsi4k1velNqv6XXvOY18eMf/zitn9letWpVWjsi4u1vf3ta+5prrmnWGjt2bLz5zW9u1ut22223pbUnTJiQ1o7437+nqhg9enTsuuuuaf0DDzwwrX3jjTemtSMitthii7R2y/fF1772tbFo0aJmvW4XXnhhWru3tzetHRFxwAEHpPbPP//8Zq3x48fHjBkzmvW63X777WntX//612ntiIj7778/rb3nnns2a+24445x1VVXNet1yzwvO+20U1o7Ivf3SGsjR46MzTffPK0/Z86ctHbmz19ExO67757Wvvrqq5u1dtlll7jlllua9bodcsghae3+/v60dkTEq1/96tT+UPkmDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQgBEHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQgBEHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACigp9PpDP3inp6hX/zfzLx581L7n/70p1P7nU6np0Wn8jMcGBhI7W+66aap/Yi4q9PpvK5FqPJzPPfcc1P7J510UmrfWYzYmPeNf0VPT5OX+P/HWYyIF154IbU/fPjw1L6zGHHTTTel9g844IDUfjiLEeF98f+q/Az/+te/pvanTZuW2g9nMSIiLrnkktT+rFmzUvvO4v+cz6i+iQMAAABQgBEHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQgBEHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQgBEHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFDBiYy5+2cteFq94xSuy7iUmTJiQ1j7vvPPS2hER999/f1r70EMPbdbq6+uLnXbaqVmv22677ZbW3mqrrdLaERFnnXVWan/u3LnNWv39/XHmmWc263WbNGlSWvvjH/94Wjsi4owzzkhrf/vb327W2mKLLWLWrFnNet2WLl2a1t56663T2hERl19+eWr/qKOOataaOHFiHHjggc163WbMmJHWnj59elo7ImLhwoVp7WOOOaZZa7vttosLLrigWa9bX19fWrvlz/KLOf3001P7n//855u1+vr6YpdddmnW65b5Wp944olp7YiIn//852ntj370o81a22yzTZxzzjnNet0uu+yytHb2+2Kn00nt9/T0NGv19/en/u6YOHFiWvuzn/1sWjsi4oQTTkhrz58/v1nrFa94Rern9dtvvz2tPWLERs0bG+3aa69N7c+cOXNI1/kmDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQgBEHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQgBEHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQwIiNubi/vz8uuOCCrHuJfffdN62dbe7cuWntxx9/vFlr0qRJ8aEPfahZr9tHPvKRtHa2n/3sZy/1LQzZ4OBgPPjgg2n9o48+Oq2dbf78+WntVatWpbVbu+yyy17qW/iX/f73v3+pb2HIhg0bFn19fWn9o446Kq2d7bDDDktrL1++vFlrcHAwli5d2qzX7dhjj01rZ7v66qtf6lsYsi222CJOPfXUtP473/nOtHa2K664Iq29cuXKZq0NGzbEunXrmvW6XXXVVWntbAcffPBLfQtDtnbt2vjlL3+Z1q/8+eaJJ55Ia7f8jDp69Oh4y1ve0qzX7eSTT05rZ7vuuute6luICN/EAQAAACjBiAMAAABQgBEHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQgBEHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQgBEHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKGLExF69evTquv/76rHuJiy66KK09YsRG/adutAceeCCtvWjRomatnp6e2GSTTZr1un3rW99Ka99zzz1p7YiIdevWpfZb6nQ60el00vrbbLNNWvvCCy9Ma0dE7L///mntF154oVlrcHAwHnrooWa9boccckhae8yYMWntiIjf/OY3qf2W1qxZE7feemta//Of/3xae+zYsWntiEj9+b7yyiubtXp7e2OXXXZp1uuW+fu05eeDF7Pzzjun9lsaGBiIe++9N63/uc99Lq09cuTItHZExKOPPprW7unpadZas2ZN3Hzzzc163Q4//PC09sEHH5zWjoj43e9+l9pv6bnnnosVK1ak9Q844IC09tlnn53Wjsj9bLZmzZpmraeffjpuuOGGZr1umc9wn332SWtHRFx99dWp/aHyTRwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQgBEHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQgBEHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQwIiNuXjzzTePOXPmZN1LnHXWWWnt17zmNWntiIgrrrgirb1y5cpmrcHBwXj44Yeb9bptueWWae0//vGPae2IiP333z+139KKFSviq1/9alr/tttuS2tvt912ae2IiAULFqS1Z8+e3aw1atSomD59erNet8HBwbT2DTfckNaOiHjlK1+Z2m9p+vTpceutt6b1jzzyyLT2G97whrR2RMT69evT2p1Op1lr6dKlcfzxxzfrdbvsssvS2r29vWntiIjzzz8/tT9z5sxmrWHDhsWYMWOa9bqNHDkyrf3MM8+ktSMibrnllrT2mjVrmrV6enpSX+cjjjgirT1u3Li0dkTEhg0bUvstTZo0KY455pi0/sUXX5zWnjt3blo7ImLbbbdNay9btqxZa9SoUbH99ts363XL/Pwxf/78tHZExPDhw1P7Q+WbOAAAAAAFGHEAAAAACjDiAAAAABRgxAEAAAAowIgDAAAAUIARBwAAAKAAIw4AAABAAUYcAAAAgAKMOAAAAAAFGHEAAAAACjDiAAAAABRgxAEAAAAowIgDAAAAUIARBwAAAKAAIw4AAABAAUYcAAAAgAKMOAAAAAAFGHEAAAAACjDiAAAAABRgxAEAAAAowIgDAAAAUIARBwAAAKAAIw4AAABAASM25uLHHnssPvaxj2XdS8yfPz+t/ba3vS2tHRGxbNmy1H4rnU4nnnvuubT+sccem9Y+4YQT0toREaeffnpqv6WpU6emvtZ77bVXWnvWrFlp7YiISy65JLXfytSpU+MTn/hEWn/MmDFp7Te84Q1p7YiI6667LrXf0vLly+MrX/lKWv+mm25Kax900EFp7YiIM844I7Xfyvjx4+O9731vWv+Nb3xjWvsjH/lIWjsi4qKLLkrttzQwMBD33HNPWv/iiy9Oa//yl79Ma0fUOYs9PT2x6aabpvUzf+fdfvvtae2IiLPPPju139I//vGP+O1vf5vWv+WWW9LamX/nRkScd955qf1WBgYG4v7770/rz5s3L609e/bstHZExB133JHaHyrfxAEAAAAowIgDAAAAUIARBwAAAKAAIw4AAABAAUYcAAAAgAKMOAAAAAAFGHEAAAAACjDiAAAAABRgxAEAAAAowIgDAAAAUIARBwAAAKAAIw4AAABAAUYcAAAAgAKMOAAAAAAFGHEAAAAACjDiAAAAABRgxAEAAAAowIgDAAAAUIARBwAAAKAAIw4AAABAAUYcAAAAgAKMOAAAAAAFGHEAAAAACujpdDpDv7inZ+gX/wt+/vOfp7X33XfftHZExI033pjWPumkk2LJkiU9LVrZz3D33XdPay9evDitHRFx4IEHpvavvfbauzqdzutatLKf45w5c9LafX19ae2IiCOOOCKt/e53vzsWL15c4iwef/zxae2Xv/zlae2IiKOOOiq139/fX+YsLliwIK39pje9Ka0dEXHPPfektWfNmhV/+tOfSpzFSy65JK39/PPPp7UjImbMmJHa33rrrcucxQceeCCtvcMOO6S1IyL22WeftPadd94Za9asKXEW77vvvrT2kiVL0toREdtuu21qf8cddyxzFleuXJnWPvHEE9PaERGPPfZYWvvuu++OtWvXljiLd911V1q7t7c3rR0RsWzZstT+vvvuO6Sz6Js4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQgBEHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQgBEHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQgBEHAAAAoIARG3Pxf/zHf8TcuXOz7iVuvfXWtPZPf/rTtHZExNNPP53WXr16dbPW5ptvHh/84Aeb9bpts802ae1Zs2altSMiRo4cmdpvadttt40LLrggrf/AAw+ktXt6etLaEREnnHBCWnvp0qXNWltuuWWcfPLJzXrdli9fntbu7e1Na0dEHH/88an9lrbffvu4+OKL0/qnnXZaWvuII45Ia0dEbL311mntDRs2NGtNnz49vv/97zfrdbvuuuvS2tlncc6cOan9lrbZZps499xz0/qZ74vf+c530toREWeffXZa+8gjj2zWmjRpUhx88MHNet0WLlyY1t5ss83S2hERe++9d2q/palTp8YHPvCBtP68efPS2vvvv39aOyLiiSeeSGs//PDDzVo77bRTLFiwoFmv24033pjW3m233dLaERFXXXVVan+ofBMHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQgBEHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQgBEHAAAAoAAjDgAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACigp9PpDP3inp4nI2Jp3u3wn3hlp9OZ3CLkGb6kPMf6PMN/D55jfZ7hvwfPsT7P8N+D51ifZ/jvYUjPcaNGHAAAAABeGv45FQAAAEABRhwAAACAAow4AAAAAAUYcQAAAAAKMOIAAAAAFGDEAQAAACjAiAMAAABQgBEHAAAAoAAjDgAAAEAB/wv5cd2Z2N3W7AAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 1440x576 with 10 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "conv_encoder = Model(x, h)  # 只取编码器做模型\n",
    "encoded_imgs = conv_encoder.predict(X_test)\n",
    "\n",
    "# 打印10张测试集手写体的压缩效果\n",
    "n = 10\n",
    "plt.figure(figsize=(20, 8))\n",
    "for i in range(n):\n",
    "    ax = plt.subplot(1, n, i+1)\n",
    "    plt.imshow(encoded_imgs[i].reshape(4, 16).T)\n",
    "    plt.gray()\n",
    "    ax.get_xaxis().set_visible(False)\n",
    "    ax.get_yaxis().set_visible(False)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 查看解码效果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 161,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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zTXXXGNxq1aton5J4+W6666LtjU9vJR7XmTjU2c0NUpTYp566qmo32effWbx4sWLLfbXKb0vfeaZZ6K2t956y+J//etfFo8bNy7qt2zZssTXR3a6/EII8RjTe03/nchqp512svjLL7+M2iZPnmzxqFGjojb9zn3++eclvXcpmIkDAAAAAACQAzzEAQAAAAAAyAEe4gAAAAAAAORAg66JoyXFQwiha9euFr/zzjtR21ZbbWVxWl5yz549LX7vvfcsTioJWBvNg5s/f77FWj7bmzlzZrRdrWviKF3/olRnnXWWxZtvvnliP81FrW0bjdfZZ59tsf/OMI4qY8SIERZrCfBSaSnVpUuXRm3t27e3WMvcvvbaa1G/lVZaaYX3o+h8PriWiZ42bZrFl112Wb3t00EHHVRv74Xv6tKlS7TdvXv3xL56b/Pkk09WbJ+Kok2bNtH2YYcdltj3uOOOs1jvGytN18F57rnnEvv5NXH8epII4cwzz7RYS8Zn5dd523fffS32Zcp1/Zz6XEOjKNLWqdl2220t1tLS3pgxYyzW35XTp0+P+rVr185iXQs1hPKsI4jv0ucBp5xyisV+jK299tq1/v37778fbb/yyisW//e//43a9DeIrs244447Rv30nNCnT5+obfz48RZrmfJKYyYOAAAAAABADvAQBwAAAAAAIAcaNJ3q+eefT91WvjTct3x5027dulms06J22GGHzPu1fPlyi6dMmWKxT/HSqVU6lR0rZv/997dYS3WuuuqqUb958+ZZ/Pvf/z5q+/TTTyu0d1hRHTp0iLZ79OhhsY63ECjFWC677757tL3FFltYrNOBs04N9tNFdTqzluoMIYQf/ehHFqeVPz755JMtvvHGGzPtR7U5//zzo22dUq5T931KW7nptc9/t5heXr/SUnw8n3aAdFdeeWW0/bOf/cxivb8MIYQHHnigXvbJ69Wrl8Xrrbde1HbbbbdZfNddd9XXLuWGpvqGEMIvfvGLWvtNmDAh2p47d67Fe+21V+LrN2/e3GJN1QohhLvvvtviOXPmfP/OVjl//3/PPfdYrOlTIcTpxGkphsqnUCm/XAbK76abboq2NQ0urVy4Pjd48803LT733HOjfvq73tt5550t1vvQW265Jeqnzxf0HBBCCDfccIPFw4cPt7jSqbXMxAEAAAAAAMgBHuIAAAAAAADkQIOm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/dZbb5V1P6rVzjvvHG0njWFf3RH55M/Dn3zyicVXXnllfe8OKuz++++3WNOpfvKTn0T9dLkBlnrI5vnnn6/1v2v6cQhxOtWXX35p8a233hr1u/nmmy3+7W9/G7UlpbmiMnbcccdoW8+Na665ZuLf6TIdWo0qhBA+++yzMu1d/WMmDgAAAAAAQA7wEAcAAAAAACAHeIgDAAAAAACQA4VbE0fXunnqqacs7tixY9Rv2rRpFmu5cdS/CRMmrPBrPPDAA9H27NmzLV5vvfUs9vnG5TZnzpxo+09/+lNF368x2XXXXaPt9ddfv4H2BCGEcOONN1p8xRVXJPbT8rVp69lkXesma78hQ4Zk6oeGoWsq1bb9LdbAqQxd089bsGCBxddee2197A4qQNdm0PuUEEKYN2+exZQULx69Tur1+aCDDor6XXjhhRbfd999UduUKVMqtHfF9Mwzz0Tben+uJamPP/74qN+mm25q8R577JHpvWbNmlXCHuL7+LUT11prrVr76ZpiIcTrTo0ePbr8O9ZAmIkDAAAAAACQAzzEAQAAAAAAyIHCpVN16tTJ4u7duyf20/LRmlqF8vGl2/000XLq169fSX+nZQXT0kAeffRRi19//fXEfq+88kpJ+1EEhxxySLStqY3jxo2z+OWXX663fapmDz30kMVnnXVW1Na6deuKve/8+fOj7XfeecfiE044wWJNeUTjU1NTk7qNytpnn30S22bOnGnx4sWL62N3UAGaTuXH1xNPPJH4d5pCsM4661is3wvkxxtvvGHxBRdcELUNGjTI4ssuuyxqO+qooyxetmxZhfauOPReJIS4zPsRRxyR+He9e/dObPvqq68s1jF7zjnnlLKLqIWe784+++xMf3P33XdH2y+99FI5d6nRYCYOAAAAAABADvAQBwAAAAAAIAd4iAMAAAAAAJADuV8Tp3379tG2LyH3Lb8mhJbVRWUceuih0bbmMq6yyiqZXmObbbaxuC7lwW+55RaLp0+fnthv+PDhFk+aNCnz6+MbzZo1s7hPnz6J/R588EGLNYcYlTNjxgyL+/fvH7UdfPDBFp966qllfV8t2xlCCDfccENZXx/1Y/XVV09sY/2FytDroq7v5y1fvtziL774oqL7hIah18kBAwZEbaeddprFEydOtPjoo4+u/I6hou64445o+8QTT7TY31NffPHFFk+YMKGy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\n",
      "text/plain": [
       "<Figure size 1440x432 with 20 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "decoded_imgs = autoencoder.predict(X_test)\n",
    "\n",
    "n = 10\n",
    "plt.figure(figsize=(20, 6))\n",
    "for i in range(n):\n",
    "    # 原图\n",
    "    ax = plt.subplot(3, n, i+1)\n",
    "    plt.imshow(X_test[i].reshape(28, 28))\n",
    "    plt.gray()\n",
    "    ax.get_xaxis().set_visible(False)\n",
    "    ax.get_yaxis().set_visible(False)\n",
    "\n",
    "    \n",
    "    # 解码效果图\n",
    "    ax = plt.subplot(3, n, i+n+1)\n",
    "    plt.imshow(decoded_imgs[i].reshape(28, 28))\n",
    "    plt.gray()\n",
    "    ax.get_xaxis().set_visible(False)\n",
    "    ax.get_yaxis().set_visible(False)\n",
    "    \n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练过程可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 162,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dict_keys(['val_loss', 'loss'])\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "print(history.history.keys())\n",
    "\n",
    "plt.plot(history.history['loss'])\n",
    "plt.plot(history.history['val_loss'])\n",
    "plt.title('model loss')\n",
    "plt.ylabel('loss')\n",
    "plt.xlabel('epoch')\n",
    "plt.legend(['train', 'validation'], loc='upper right')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***\n",
    "# 3.卷积自编码器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 读取数据集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 163,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "X_train shape: (60000, 28, 28, 1)\n",
      "60000 train samples\n",
      "10000 test samples\n"
     ]
    }
   ],
   "source": [
    "nb_classes = 10  # 10类\n",
    "\n",
    "(X_train, y_train), (X_test, y_test) = mnist.load_data()\n",
    "\n",
    "X_train = X_train.reshape(X_train.shape[0], 28, 28, 1)\n",
    "X_test = X_test.reshape(X_test.shape[0], 28, 28, 1)\n",
    "\n",
    "# 归一化\n",
    "X_train = X_train.astype(\"float32\")/255.\n",
    "X_test = X_test.astype(\"float32\")/255.\n",
    "print('X_train shape:', X_train.shape)\n",
    "print(X_train.shape[0], 'train samples')\n",
    "print(X_test.shape[0], 'test samples')\n",
    "\n",
    "y_train = np_utils.to_categorical(y_train, nb_classes)\n",
    "y_test = np_utils.to_categorical(y_test, nb_classes)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 卷积自编码器建模"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 164,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = Input(shape=(28, 28,1)) \n",
    "\n",
    "# 编码器\n",
    "conv1_1 = Conv2D(16, (3, 3), activation='relu', padding='same')(x)\n",
    "pool1 = MaxPooling2D((2, 2), padding='same')(conv1_1)\n",
    "conv1_2 = Conv2D(8, (3, 3), activation='relu', padding='same')(pool1)\n",
    "pool2 = MaxPooling2D((2, 2), padding='same')(conv1_2)\n",
    "conv1_3 = Conv2D(8, (3, 3), activation='relu', padding='same')(pool2)\n",
    "h = MaxPooling2D((2, 2), padding='same')(conv1_3)\n",
    "\n",
    "\n",
    "# 解码器\n",
    "conv2_1 = Conv2D(8, (3, 3), activation='relu', padding='same')(h)\n",
    "up1 = UpSampling2D((2, 2))(conv2_1)\n",
    "conv2_2 = Conv2D(8, (3, 3), activation='relu', padding='same')(up1)\n",
    "up2 = UpSampling2D((2, 2))(conv2_2)\n",
    "conv2_3 = Conv2D(16, (3, 3), activation='relu')(up2)\n",
    "up3 = UpSampling2D((2, 2))(conv2_3)\n",
    "r = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(up3)\n",
    "\n",
    "autoencoder = Model(inputs=x, outputs=r)\n",
    "autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 模型可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 165,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<svg height=\"994pt\" viewBox=\"0.00 0.00 275.00 994.00\" width=\"275pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g class=\"graph\" id=\"graph0\" transform=\"scale(1 1) rotate(0) translate(4 990)\">\n",
       "<title>G</title>\n",
       "<polygon fill=\"white\" points=\"-4,4 -4,-990 271,-990 271,4 -4,4\" stroke=\"none\"/>\n",
       "<!-- 140641025241440 -->\n",
       "<g class=\"node\" id=\"node1\"><title>140641025241440</title>\n",
       "<polygon fill=\"none\" points=\"49,-949.5 49,-985.5 218,-985.5 218,-949.5 49,-949.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-963.8\">input_30: InputLayer</text>\n",
       "</g>\n",
       "<!-- 140641025241384 -->\n",
       "<g class=\"node\" id=\"node2\"><title>140641025241384</title>\n",
       "<polygon fill=\"none\" points=\"53.5,-876.5 53.5,-912.5 213.5,-912.5 213.5,-876.5 53.5,-876.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-890.8\">conv2d_20: Conv2D</text>\n",
       "</g>\n",
       "<!-- 140641025241440&#45;&gt;140641025241384 -->\n",
       "<g class=\"edge\" id=\"edge1\"><title>140641025241440-&gt;140641025241384</title>\n",
       "<path d=\"M133.5,-949.313C133.5,-941.289 133.5,-931.547 133.5,-922.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"137,-922.529 133.5,-912.529 130,-922.529 137,-922.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641025241608 -->\n",
       "<g class=\"node\" id=\"node3\"><title>140641025241608</title>\n",
       "<polygon fill=\"none\" points=\"6.5,-803.5 6.5,-839.5 260.5,-839.5 260.5,-803.5 6.5,-803.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-817.8\">max_pooling2d_9: MaxPooling2D</text>\n",
       "</g>\n",
       "<!-- 140641025241384&#45;&gt;140641025241608 -->\n",
       "<g class=\"edge\" id=\"edge2\"><title>140641025241384-&gt;140641025241608</title>\n",
       "<path d=\"M133.5,-876.313C133.5,-868.289 133.5,-858.547 133.5,-849.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"137,-849.529 133.5,-839.529 130,-849.529 137,-849.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641025241944 -->\n",
       "<g class=\"node\" id=\"node4\"><title>140641025241944</title>\n",
       "<polygon fill=\"none\" points=\"53.5,-730.5 53.5,-766.5 213.5,-766.5 213.5,-730.5 53.5,-730.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-744.8\">conv2d_21: Conv2D</text>\n",
       "</g>\n",
       "<!-- 140641025241608&#45;&gt;140641025241944 -->\n",
       "<g class=\"edge\" id=\"edge3\"><title>140641025241608-&gt;140641025241944</title>\n",
       "<path d=\"M133.5,-803.313C133.5,-795.289 133.5,-785.547 133.5,-776.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"137,-776.529 133.5,-766.529 130,-776.529 137,-776.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641025241832 -->\n",
       "<g class=\"node\" id=\"node5\"><title>140641025241832</title>\n",
       "<polygon fill=\"none\" points=\"2,-657.5 2,-693.5 265,-693.5 265,-657.5 2,-657.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-671.8\">max_pooling2d_10: MaxPooling2D</text>\n",
       "</g>\n",
       "<!-- 140641025241944&#45;&gt;140641025241832 -->\n",
       "<g class=\"edge\" id=\"edge4\"><title>140641025241944-&gt;140641025241832</title>\n",
       "<path d=\"M133.5,-730.313C133.5,-722.289 133.5,-712.547 133.5,-703.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"137,-703.529 133.5,-693.529 130,-703.529 137,-703.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641025206480 -->\n",
       "<g class=\"node\" id=\"node6\"><title>140641025206480</title>\n",
       "<polygon fill=\"none\" points=\"53.5,-584.5 53.5,-620.5 213.5,-620.5 213.5,-584.5 53.5,-584.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-598.8\">conv2d_22: Conv2D</text>\n",
       "</g>\n",
       "<!-- 140641025241832&#45;&gt;140641025206480 -->\n",
       "<g class=\"edge\" id=\"edge5\"><title>140641025241832-&gt;140641025206480</title>\n",
       "<path d=\"M133.5,-657.313C133.5,-649.289 133.5,-639.547 133.5,-630.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"137,-630.529 133.5,-620.529 130,-630.529 137,-630.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641025207152 -->\n",
       "<g class=\"node\" id=\"node7\"><title>140641025207152</title>\n",
       "<polygon fill=\"none\" points=\"2,-511.5 2,-547.5 265,-547.5 265,-511.5 2,-511.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-525.8\">max_pooling2d_11: MaxPooling2D</text>\n",
       "</g>\n",
       "<!-- 140641025206480&#45;&gt;140641025207152 -->\n",
       "<g class=\"edge\" id=\"edge6\"><title>140641025206480-&gt;140641025207152</title>\n",
       "<path d=\"M133.5,-584.313C133.5,-576.289 133.5,-566.547 133.5,-557.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"137,-557.529 133.5,-547.529 130,-557.529 137,-557.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641024889128 -->\n",
       "<g class=\"node\" id=\"node8\"><title>140641024889128</title>\n",
       "<polygon fill=\"none\" points=\"53.5,-438.5 53.5,-474.5 213.5,-474.5 213.5,-438.5 53.5,-438.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-452.8\">conv2d_23: Conv2D</text>\n",
       "</g>\n",
       "<!-- 140641025207152&#45;&gt;140641024889128 -->\n",
       "<g class=\"edge\" id=\"edge7\"><title>140641025207152-&gt;140641024889128</title>\n",
       "<path d=\"M133.5,-511.313C133.5,-503.289 133.5,-493.547 133.5,-484.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"137,-484.529 133.5,-474.529 130,-484.529 137,-484.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641024890472 -->\n",
       "<g class=\"node\" id=\"node9\"><title>140641024890472</title>\n",
       "<polygon fill=\"none\" points=\"4.5,-365.5 4.5,-401.5 262.5,-401.5 262.5,-365.5 4.5,-365.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-379.8\">up_sampling2d_9: UpSampling2D</text>\n",
       "</g>\n",
       "<!-- 140641024889128&#45;&gt;140641024890472 -->\n",
       "<g class=\"edge\" id=\"edge8\"><title>140641024889128-&gt;140641024890472</title>\n",
       "<path d=\"M133.5,-438.313C133.5,-430.289 133.5,-420.547 133.5,-411.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"137,-411.529 133.5,-401.529 130,-411.529 137,-411.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641024990736 -->\n",
       "<g class=\"node\" id=\"node10\"><title>140641024990736</title>\n",
       "<polygon fill=\"none\" points=\"53.5,-292.5 53.5,-328.5 213.5,-328.5 213.5,-292.5 53.5,-292.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-306.8\">conv2d_24: Conv2D</text>\n",
       "</g>\n",
       "<!-- 140641024890472&#45;&gt;140641024990736 -->\n",
       "<g class=\"edge\" id=\"edge9\"><title>140641024890472-&gt;140641024990736</title>\n",
       "<path d=\"M133.5,-365.313C133.5,-357.289 133.5,-347.547 133.5,-338.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"137,-338.529 133.5,-328.529 130,-338.529 137,-338.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641025098024 -->\n",
       "<g class=\"node\" id=\"node11\"><title>140641025098024</title>\n",
       "<polygon fill=\"none\" points=\"0,-219.5 0,-255.5 267,-255.5 267,-219.5 0,-219.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-233.8\">up_sampling2d_10: UpSampling2D</text>\n",
       "</g>\n",
       "<!-- 140641024990736&#45;&gt;140641025098024 -->\n",
       "<g class=\"edge\" id=\"edge10\"><title>140641024990736-&gt;140641025098024</title>\n",
       "<path d=\"M133.5,-292.313C133.5,-284.289 133.5,-274.547 133.5,-265.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"137,-265.529 133.5,-255.529 130,-265.529 137,-265.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641024652736 -->\n",
       "<g class=\"node\" id=\"node12\"><title>140641024652736</title>\n",
       "<polygon fill=\"none\" points=\"53.5,-146.5 53.5,-182.5 213.5,-182.5 213.5,-146.5 53.5,-146.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-160.8\">conv2d_25: Conv2D</text>\n",
       "</g>\n",
       "<!-- 140641025098024&#45;&gt;140641024652736 -->\n",
       "<g class=\"edge\" id=\"edge11\"><title>140641025098024-&gt;140641024652736</title>\n",
       "<path d=\"M133.5,-219.313C133.5,-211.289 133.5,-201.547 133.5,-192.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"137,-192.529 133.5,-182.529 130,-192.529 137,-192.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641024652176 -->\n",
       "<g class=\"node\" id=\"node13\"><title>140641024652176</title>\n",
       "<polygon fill=\"none\" points=\"0,-73.5 0,-109.5 267,-109.5 267,-73.5 0,-73.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-87.8\">up_sampling2d_11: UpSampling2D</text>\n",
       "</g>\n",
       "<!-- 140641024652736&#45;&gt;140641024652176 -->\n",
       "<g class=\"edge\" id=\"edge12\"><title>140641024652736-&gt;140641024652176</title>\n",
       "<path d=\"M133.5,-146.313C133.5,-138.289 133.5,-128.547 133.5,-119.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"137,-119.529 133.5,-109.529 130,-119.529 137,-119.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641024347944 -->\n",
       "<g class=\"node\" id=\"node14\"><title>140641024347944</title>\n",
       "<polygon fill=\"none\" points=\"53.5,-0.5 53.5,-36.5 213.5,-36.5 213.5,-0.5 53.5,-0.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-14.8\">conv2d_26: Conv2D</text>\n",
       "</g>\n",
       "<!-- 140641024652176&#45;&gt;140641024347944 -->\n",
       "<g class=\"edge\" id=\"edge13\"><title>140641024652176-&gt;140641024347944</title>\n",
       "<path d=\"M133.5,-73.3129C133.5,-65.2895 133.5,-55.5475 133.5,-46.5691\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"137,-46.5288 133.5,-36.5288 130,-46.5289 137,-46.5288\" stroke=\"black\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>"
      ],
      "text/plain": [
       "<IPython.core.display.SVG object>"
      ]
     },
     "execution_count": 165,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from IPython.display import SVG\n",
    "from keras.utils.vis_utils import model_to_dot\n",
    "\n",
    "SVG(model_to_dot(autoencoder).create(prog='dot', format='svg'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 166,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 60000 samples, validate on 10000 samples\n",
      "Epoch 1/3\n",
      "60000/60000 [==============================] - 65s 1ms/step - loss: 0.2138 - val_loss: 0.1643\n",
      "Epoch 2/3\n",
      "60000/60000 [==============================] - 62s 1ms/step - loss: 0.1528 - val_loss: 0.1448\n",
      "Epoch 3/3\n",
      "60000/60000 [==============================] - 62s 1ms/step - loss: 0.1385 - val_loss: 0.1295\n"
     ]
    }
   ],
   "source": [
    "epochs = 3\n",
    "batch_size = 128\n",
    "\n",
    "history = autoencoder.fit(X_train, X_train, \n",
    "                          batch_size=batch_size, \n",
    "                          epochs=epochs, verbose=1, \n",
    "                          validation_data=(X_test, X_test)\n",
    "                         )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 查看解码效果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 167,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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h313RySTvw7/8MMPFv/zn//M9+4gx/79739brOlUZ5xxRjRPyw1Q6iEzw4YNK/PfNf04hDid6ueff7b4iSeeiOY99thjFv/1r3+NxlKluSI3OnXqFG3rtbFatWopf07LdGg3qhBC+Omnn7K0d/nHShwAAAAAAIAE4CEOAAAAAABAAvAQBwAAAAAAIAEKriaO1roZMmSIxY0bN47mffXVVxZru3Hk38SJEzf7NZ5//vloe/78+RbXqVPHYp9vnG0LFiyItm+99dac/r7KpEuXLtF23bp1K2hPEEIIDz30kMW33357ynnavjZdPZtMa91kOu/hhx/OaB4qhtZUKmv7V9TAyQ2t6ectXrzY4nvuuScfu4Mc0NoMep8SQgjfffedxbQULzz6OamfzyeeeGI074YbbrB4wIAB0dj06dNztHeF6e2334629f5cW1Kfd9550bymTZtafOihh2b0u+bOnVuOPcTG+NqJO+ywQ5nztKZYCHHdqdGjR2d/xyoIK3EAAAAAAAASgIc4AAAAAAAACVBw6VRNmjSxuH379innaftoTa1C9vjW7X6ZaDaddtpp5fo5bSuYLg3k1VdftXjcuHEp540cObJc+1EITj755GhbUxs//fRTi99///287VMxGzRokMW9e/eOxmrVqpWz37to0aJo+4svvrD4/PPPt1hTHlH5lJaWpt1Gbh111FEpx2bPnm3xihUr8rE7yAFNp/Ln1+DBg1P+nKYQ7LTTThbr+wLJ8dlnn1l8/fXXR2N9+/a1+LbbbovGfv/731u8evXqHO1d4dB7kRDiNu+nn356yp/r2rVryrFffvnFYj1nr7766vLsIsqg17srr7wyo5955plnou0RI0Zkc5cqDVbiAAAAAAAAJAAPcQAAAAAAABKAhzgAAAAAAAAJkPiaOA0bNoy2fQu5X/maENpWF7lxyimnRNuay7jllltm9BotWrSweFPagz/++OMWz5w5M+W8F1980eKpU6dm/Pr4j+22287i7t27p5z3wgsvWKw5xMidWbNmWdyzZ89o7KSTTrL40ksvzerv1badIYTwwAMPZPX1kR/bbLNNyjHqL+SGfi5qfT9vzZo1Fq9bty6n+4SKoZ+TZ511VjR22WWXWTx58mSL//CHP+R+x5BT/fr1i7YvuOACi/099U033WTxxIkTc7tjBcB/bv31r3+1uFq1ahZ3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\n",
      "text/plain": [
       "<Figure size 1440x432 with 20 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "decoded_imgs = autoencoder.predict(X_test)\n",
    "\n",
    "n = 10\n",
    "plt.figure(figsize=(20, 6))\n",
    "for i in range(n):\n",
    "    # 原图\n",
    "    ax = plt.subplot(3, n, i+1)\n",
    "    plt.imshow(X_test[i].reshape(28, 28))\n",
    "    plt.gray()\n",
    "    ax.get_xaxis().set_visible(False)\n",
    "    ax.get_yaxis().set_visible(False)\n",
    "\n",
    "    \n",
    "    # 解码效果图\n",
    "    ax = plt.subplot(3, n, i+n+1)\n",
    "    plt.imshow(decoded_imgs[i].reshape(28, 28))\n",
    "    plt.gray()\n",
    "    ax.get_xaxis().set_visible(False)\n",
    "    ax.get_yaxis().set_visible(False)\n",
    "    \n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练过程可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 168,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dict_keys(['val_loss', 'loss'])\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "print(history.history.keys())\n",
    "\n",
    "plt.plot(history.history['loss'])\n",
    "plt.plot(history.history['val_loss'])\n",
    "plt.title('model loss')\n",
    "plt.ylabel('loss')\n",
    "plt.xlabel('epoch')\n",
    "plt.legend(['train', 'validation'], loc='upper right')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***\n",
    "# 4.正则自编码器  \n",
    "两种类型：  \n",
    "1.稀疏正则自编码器  \n",
    "2.去噪正则自编码器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.稀疏正则自编码器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 读取数据集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 183,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "X_train shape: (60000, 28, 28)\n",
      "60000 train samples\n",
      "10000 test samples\n"
     ]
    }
   ],
   "source": [
    "(X_train, _), (X_test, _) = mnist.load_data()\n",
    "\n",
    "#  归一化\n",
    "X_train = X_train.astype(\"float32\")/255.\n",
    "X_test = X_test.astype(\"float32\")/255.\n",
    "\n",
    "print('X_train shape:', X_train.shape)\n",
    "print(X_train.shape[0], 'train samples')\n",
    "print(X_test.shape[0], 'test samples')\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### np.prod是将28X28矩阵转化成1X784，方便BP神经网络输入层784个神经元读取。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 184,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train = X_train.reshape((len(X_train), np.prod(X_train.shape[1:])))\n",
    "X_test = X_test.reshape((len(X_test), np.prod(X_test.shape[1:])))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 稀疏正则自编码器建模"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 185,
   "metadata": {},
   "outputs": [],
   "source": [
    "input_size = 784\n",
    "hidden_size = 32\n",
    "output_size = 784\n",
    "\n",
    "x = Input(shape=(input_size,))\n",
    "h = Dense(hidden_size, activation='relu', activity_regularizer=regularizers.l1(10e-5))(x)\n",
    "r = Dense(output_size, activation='sigmoid')(h)\n",
    "\n",
    "autoencoder = Model(inputs=x, outputs=r)\n",
    "autoencoder.compile(optimizer='adam', loss='mse')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 186,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 60000 samples, validate on 10000 samples\n",
      "Epoch 1/15\n",
      "60000/60000 [==============================] - 4s 65us/step - loss: 0.1948 - val_loss: 0.1632\n",
      "Epoch 2/15\n",
      "60000/60000 [==============================] - 2s 39us/step - loss: 0.1416 - val_loss: 0.1242\n",
      "Epoch 3/15\n",
      "60000/60000 [==============================] - 2s 39us/step - loss: 0.1120 - val_loss: 0.1025\n",
      "Epoch 4/15\n",
      "60000/60000 [==============================] - 2s 38us/step - loss: 0.0954 - val_loss: 0.0901\n",
      "Epoch 5/15\n",
      "60000/60000 [==============================] - 2s 39us/step - loss: 0.0857 - val_loss: 0.0826\n",
      "Epoch 6/15\n",
      "60000/60000 [==============================] - 2s 38us/step - loss: 0.0798 - val_loss: 0.0780\n",
      "Epoch 7/15\n",
      "60000/60000 [==============================] - 2s 38us/step - loss: 0.0760 - val_loss: 0.0749\n",
      "Epoch 8/15\n",
      "60000/60000 [==============================] - 2s 38us/step - loss: 0.0735 - val_loss: 0.0729\n",
      "Epoch 9/15\n",
      "60000/60000 [==============================] - 2s 38us/step - loss: 0.0718 - val_loss: 0.0714\n",
      "Epoch 10/15\n",
      "60000/60000 [==============================] - 2s 38us/step - loss: 0.0706 - val_loss: 0.0704\n",
      "Epoch 11/15\n",
      "60000/60000 [==============================] - 2s 39us/step - loss: 0.0698 - val_loss: 0.0697\n",
      "Epoch 12/15\n",
      "60000/60000 [==============================] - 2s 39us/step - loss: 0.0692 - val_loss: 0.0691\n",
      "Epoch 13/15\n",
      "60000/60000 [==============================] - 2s 39us/step - loss: 0.0687 - val_loss: 0.0688\n",
      "Epoch 14/15\n",
      "60000/60000 [==============================] - 2s 39us/step - loss: 0.0684 - val_loss: 0.0684\n",
      "Epoch 15/15\n",
      "60000/60000 [==============================] - 2s 40us/step - loss: 0.0681 - val_loss: 0.0682\n"
     ]
    }
   ],
   "source": [
    "epochs = 15\n",
    "batch_size = 128\n",
    "\n",
    "history = autoencoder.fit(X_train, X_train, \n",
    "                          batch_size=batch_size, \n",
    "                          epochs=epochs, \n",
    "                          verbose=1, \n",
    "                          validation_data=(X_test, X_test)\n",
    "                         )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 模型可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 173,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<svg height=\"191pt\" viewBox=\"0.00 0.00 177.00 191.00\" width=\"177pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g class=\"graph\" id=\"graph0\" transform=\"scale(1 1) rotate(0) translate(4 187)\">\n",
       "<title>G</title>\n",
       "<polygon fill=\"white\" points=\"-4,4 -4,-187 173,-187 173,4 -4,4\" stroke=\"none\"/>\n",
       "<!-- 140641036015824 -->\n",
       "<g class=\"node\" id=\"node1\"><title>140641036015824</title>\n",
       "<polygon fill=\"none\" points=\"-1.42109e-14,-146.5 -1.42109e-14,-182.5 169,-182.5 169,-146.5 -1.42109e-14,-146.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"84.5\" y=\"-160.8\">input_31: InputLayer</text>\n",
       "</g>\n",
       "<!-- 140641036015208 -->\n",
       "<g class=\"node\" id=\"node2\"><title>140641036015208</title>\n",
       "<polygon fill=\"none\" points=\"16,-73.5 16,-109.5 153,-109.5 153,-73.5 16,-73.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"84.5\" y=\"-87.8\">dense_56: Dense</text>\n",
       "</g>\n",
       "<!-- 140641036015824&#45;&gt;140641036015208 -->\n",
       "<g class=\"edge\" id=\"edge1\"><title>140641036015824-&gt;140641036015208</title>\n",
       "<path d=\"M84.5,-146.313C84.5,-138.289 84.5,-128.547 84.5,-119.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"88.0001,-119.529 84.5,-109.529 81.0001,-119.529 88.0001,-119.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641036015712 -->\n",
       "<g class=\"node\" id=\"node3\"><title>140641036015712</title>\n",
       "<polygon fill=\"none\" points=\"16,-0.5 16,-36.5 153,-36.5 153,-0.5 16,-0.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"84.5\" y=\"-14.8\">dense_57: Dense</text>\n",
       "</g>\n",
       "<!-- 140641036015208&#45;&gt;140641036015712 -->\n",
       "<g class=\"edge\" id=\"edge2\"><title>140641036015208-&gt;140641036015712</title>\n",
       "<path d=\"M84.5,-73.3129C84.5,-65.2895 84.5,-55.5475 84.5,-46.5691\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"88.0001,-46.5288 84.5,-36.5288 81.0001,-46.5289 88.0001,-46.5288\" stroke=\"black\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>"
      ],
      "text/plain": [
       "<IPython.core.display.SVG object>"
      ]
     },
     "execution_count": 173,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from IPython.display import SVG\n",
    "from keras.utils.vis_utils import model_to_dot\n",
    "\n",
    "SVG(model_to_dot(autoencoder).create(prog='dot', format='svg'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 查看解码效果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 187,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABHEAAADnCAYAAACZmMoMAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzt3Xm8TfX+x/GvlKJBmZOZBiJKaKBSGogiSdH9NdA83m7TLbfb3ONSus3i3iaZGqhESl1EqBAyh5Ayk4ylnN8fPfr0/n6dve1z7OGsvV/Pvz6r79c+6+6119prr/v9fD7F8vLyHAAAAAAAAIq2vTK9AwAAAAAAANg9HuIAAAAAAABEAA9xAAAAAAAAIoCHOAAAAAAAABHAQxwAAAAAAIAI4CEOAAAAAABABPAQBwAAAAAAIAJ4iAMAAAAAABABPMQBAAAAAACIAB7iAAAAAAAARMDeBZlcrFixvFTtCOLLy8srlozX4Rhm1Nq8vLzyyXghjmPmcC5mBc7FLMC5mBU4F7MA52JW4FzMApyLWSGhc5GVOED6LM30DgBwznEuAkUF5yJQNHAuAkVDQuciD3EAAAAAAAAigIc4AAAAAAAAEcBDHAAAAAAAgAjgIQ4AAAAAAEAE8BAHAAAAAAAgAniIAwAAAAAAEAE8xAEAAAAAAIiAvTO9A8hNt99+u8UlS5b0xo455hiLL7zwwpiv8cILL1g8adIkb6x///57uosAAAAAABQprMQBAAAAAACIAB7iAAAAAAAARAAPcQAAAAAAACKAmjhImyFDhlgcr9aN2rlzZ8yxa665xuJWrVp5Y+PGjbN42bJlie4iMuyII47wtufNm2fxLbfcYvEzzzyTtn3KZfvvv7/FvXr1sljPPeecmzp1qsWdOnXyxpYuXZqivQMAAMiMQw45xOJq1aol9G/Ce6K//vWvFs+aNcviBQsWePNmzJhRmF1EFmMlDgAAAAAAQATwEAcAAAAAACACSKdCymj6lHOJp1BpCs2HH35oca1atbx57dq1s7h27dreWNeuXS1+7LHHEvq7yLxjjz3W29Z0uuXLl6d7d3LeoYceavFVV11lcZjm2LhxY4vbtm3rjT333HMp2juo4447zuKhQ4d6YzVq1EjZ3z3rrLO87blz51r83XffpezvYvf0O9I559577z2Lb7zxRov79Onjzfvtt99Su2NZqEKFCha/8cYbFk+cONGb17dvX4uXLFmS8v36Q+nSpb3tU045xeJRo0ZZvGPHjrTtExAF5557rsXnnXeeN3baaadZXKdOnYReL0yTql69usX77rtvzH9XvHjxhF4fuYOVOAAAAAAAABHAQxwAAAAAAIAIIJ0KSXX88cdb3KFDh5jzZs+ebXG4PHHt2rUWb9682eISJUp48yZPnmxxw4YNvbGyZcsmuMcoSho1auRtb9myxeJhw4ale3dyTvny5b3tV199NUN7goI6++yzLY63JDvZwpSdK6+80uKLL744bfuB3+l33/PPPx9z3rPPPmvxSy+95I1t27Yt+TuWZbQrjXP+PY2mLq1atcqbl6kUKu0g6Jx/rdd02IULF6Z+xyLmoIMO8rY1Rb9+/foWh11SSU0r2rQMww033GCxpo4751zJkiUtLlas2B7/3bALK1BYrMQBAAAAAACIAB7iAAAAAAAARAAPcQAAAAAAACIgozVxwpbTmof4ww8/eGPbt2+3eMCAARavXLnSm0c+b2ZpS+Iwd1RzxrV+w4oVKxJ67b/97W/edr169WLOHTFiREKviczTnHJte+ucc/3790/37uScm2++2eL27dt7Y02bNi3w62nrWuec22uvP/+/ghkzZlj86aefFvi14dt77z+/wtu0aZORfQhrbdx2220W77///t6Y1rhCauj5V6VKlZjzBg0aZLHeXyG2cuXKWTxkyBBvrEyZMhZrLaKbbrop9TsWQ48ePSyuWbOmN3bNNddYzH3zrrp27WrxI4884o1VrVo1338T1s5Zt25d8ncMSaPXx1tuuSWlf2vevHkW628hJI+2eNdrtXN+jVZtC++cczt37rS4T58+Fn/22WfevKJ4nWQlDgAAAAAAQATwEAcAAAAAACACMppO1bNnT2+7Ro0aCf07XQa6adMmbyydy9SWL19ucfi/ZcqUKWnbj6Jk+PDhFuvSNuf8Y7V+/foCv3bYrnafffYp8Gug6DnqqKMsDtMvwiXrSL4nn3zSYl1WWlgXXHBBzO2lS5da3LlzZ29emJaD3WvZsqXFJ554osXh91Eqha2WNc21VKlS3hjpVMkXtpO/9957E/p3mqqal5eX1H3KVscdd5zF4ZJ89eCDD6Zhb3Z19NFHe9uagj5s2DBvjO/WXWl6zb///W+Ly5Yt682Ldb4888wz3ramhxfmnheJCVNnNDVKU2JGjRrlzfv5558t3rhxo8Xh95Tel3700Ufe2KxZsyz+/PPPLf7qq6+8edu2bYv5+kicll9wzj/H9F4z/EwkqlmzZhb/+uuv3tj8+fMtnjBhgjemn7lffvmlUH+7MFiJAwAAAAAAEAE8xAEAAAAAAIgAHuIAAAAAAABEQEZr4mhLceecO+aYYyyeO3euN1a3bl2L4+Uln3DCCRZ/9913FsdqCZgfzYNbs2aNxdo+O7Rs2TJvO1dr4iitf1FYd9xxh8VHHHFEzHmai5rfNoquO++80+LwM8N5lBojR460WFuAF5a2Ut28ebM3Vr16dYu1ze0XX3zhzStevPge70e2C/PBtU30okWLLH700UfTtk/nn39+2v4WdtWgQQNvu3HjxjHn6r3NBx98kLJ9yhYVKlTwtjt27Bhzbrdu3SzW+8ZU0zo4H3/8ccx5YU2csJ4knLv99tst1pbxiQrrvJ1zzjkWh23KtX5OOmtoZIt4dWoaNmxosbaWDk2ePNli/V25ZMkSb161atUs1lqoziWnjiB2pc8DbrjhBovDc+yggw7K999///333vb48eMt/vbbb70x/Q2itRmbNm3qzdNrQps2bbyxGTNmWKxtylONlTgAAAAAAAARwEMcAAAAAACACMhoOtUnn3wSd1uFreH+ELY3bdSokcW6LKpJkyYJ79f27dstXrBggcVhipcurdKl7Ngzbdu2tVhbdZYoUcKbt3r1aov//ve/e2Nbt25N0d5hT9WoUcPbPv744y3W8805WjEmy6mnnuptH3nkkRbrcuBElwaHy0V1ObO26nTOudNPP93ieO2Pr7vuOotfeOGFhPYj1/To0cPb1iXlunQ/TGlLNv3uCz9bLC9Pr3gpPqEw7QDxPfHEE972pZdearHeXzrn3JtvvpmWfQq1aNHC4ooVK3pjr7zyisWvv/56unYpMjTV1znnrrjiinznzZw509tetWqVxa1atYr5+qVLl7ZYU7Wcc27AgAEWr1y5cvc7m+PC+/+BAwdarOlTzvnpxPFSDFWYQqXCchlIvhdffNHb1jS4eO3C9bnB119/bfE999zjzdPf9aGTTjrJYr0Pfemll7x5+nxBrwHOOffcc89Z/Pbbb1uc6tRaVuIAAAAAAABEAA9xAAAAAAAAIiCj6VTJsGHDBm97zJgx+c6Ll6oVjy5VDlO3dOnWkCFDCvX62JWm14RLKJW+5+PGjUvpPiF5wvQLlc6uHtlO09YGDx7sjcVbnqq0W5guEX3ggQe8efHSF/U1rr76aovLly/vzevZs6fF++23nzf27LPPWrxjx47d7XZWufDCCy0OOyIsXLjQ4nR2ctO0uDB9auzYsRb/+OOP6dqlnHXKKafEHAu73sRLZ8Su8vLyvG39rP/www/eWCo7DJUsWdLb1lSB66+/3uJwf6+88sqU7VM20PQI55w78MADLdZuNuE9i34/XXLJJRaHKRy1a9e2uFKlSt7Yu+++a3Hr1q0tXr9+fUL7ngsOOOAAi8OSCVp2Ye3atd7Y448/bjGlFYqO8L5Ou0J1797dGytWrJjF+rsgTLXv1auXxYUtv1C2bFmLtUvq/fff783Tsi5hKmamsBIHAAAAAAAgAniIAwAAAAAAEAE8xAEAAAAAAIiAyNfESYUKFSpY/Pzzz1u8117+My9tf00ea+G988473vZZZ52V77zXXnvN2w7b7SIaGjRoEHNM66Jgz+y995+X90Rr4IS1pS6++GKLw7zzRGlNnMcee8zi3r17e/NKlSplcfg5eO+99yxetGhRofYjqjp16mSxvkfO+d9PqaY1lrp27Wrxb7/95s17+OGHLc61+kXpoi1RNQ6FNQKmT5+esn3KNeeee663re3btRZUWMMhUVqH5bTTTvPGTjjhhHz/zVtvvVWov5Wr9t13X29bawo9+eSTMf+dtit++eWXLdZrtXPO1apVK+ZraK2WVNZTirL27dtbfPfdd3tj2va7RYsW3tjGjRtTu2MolPA6dscdd1isNXCcc+7777+3WGvTfvHFF4X621rrpmrVqt6Y/rYcOXKkxWEdXBXub//+/S1OZy1AVuIAAAAAAABEAA9xAAAAAAAAIoB0qnzccMMNFmsb3LCd+fz589O2T9nm0EMPtThcDq5LXDWFQ5fpO+fc5s2bU7R3SDZd/n3FFVd4Y1999ZXFo0ePTts+4XfamjpsSVvYFKpYNC1KU3Kcc65JkyZJ/VtRVbp0aW87VuqEc4VP1SgMbQ+v6Xlz58715o0ZMyZt+5SrEj1X0vn5yEZPPfWUt92yZUuLK1eu7I1pq3ddan/eeecV6m/ra4Stw9XixYstDltcIz5tDx7SdLkw5T+W448/PuG/PXnyZIu5l81fvFRRvW9cvnx5OnYHe0hTmpzbNRVb/frrrxY3a9bM4gsvvNCbd9RRR+X777dt2+Zt161bN9/YOf8+t2LFijH3Sa1atcrbzlQaOStxAAAAAAAAIoCHOAAAAAAAABFAOpVz7uSTT/a2wyrof9BK6c45N2vWrJTtU7Z7++23LS5btmzMea+//rrFudaVJpu0atXK4jJlynhjo0aNsli7PiB5ws56SpeqppqmCIT7FG8f77//fov/8pe/JH2/ipKwY8phhx1m8aBBg9K9O6Z27dr5/ne+B9MvXtpGMjoj4XdTp071to855hiLGzVq5I2dc845FmvXlTVr1njzXn311YT+tnY7mTFjRsx5EydOtJh7pIIJr6ea+qYpi2HKhnbY7NChg8VhNxs9F8Oxq666ymI91nPmzElo33NBmDqj9Hz75z//6Y29++67FtORr+j43//+521r6rX+RnDOuWrVqln89NNPWxwvtVTTs8LUrXhipVDt3LnT2x42bJjFN998sze2YsWKhP9eMrESBwAAAAAAIAJ4iAMAAAAAABABPMQBAAAAAACIAGriOOfatGnjbe+zzz4Wf/LJJxZPmjQpbfuUjTTf+Ljjjos5b+zYsRaHua6IpoYNG1oc5rS+9dZb6d6dnHDttddaHOb2Zkq7du0sPvbYY70x3cdwf7UmTrbbtGmTt605/VqTwzm/vtT69euTuh8VKlTwtmPVJ5gwYUJS/y7y17x5c4u7dOkSc97GjRstpvVucm3YsMFirecQbt911117/Ldq1aplsdYSc86/Jtx+++17/Ldy1ccff+xt67mjdW/COjWx6nKEr3fDDTdY/P7773tjhx9+uMVaX0O/t3Nd+fLlLQ7vCbR23H333eeN9ejRw+I+ffpYrG3dnfPrrixcuNDi2bNnx9yno48+2tvW34Vcb+ML235rPamDDz7YG9PatFq3dt26dd68ZcuWWayfCf3N4ZxzTZs2LfD+9u3b19u+5557LNZ6V5nEShwAAAAAAIAI4CEOAAAAAABABORsOlXJkiUt1lZ1zjn3yy+/WKzpPDt27Ej9jmWRsHW4LkXTlLWQLhXevHlz8ncMaVGpUiWLW7RoYfH8+fO9edq2D8mjqUvppEugnXOuXr16Fus1IJ6wLW8uXXvDJcfaNrhjx47e2IgRIyzu3bt3gf9W/fr1vW1N4ahRo4Y3FiuFoKik6mU7/T7da6/Y///b6NGj07E7SDFNEQnPPU3XCq+VSFyYgnrRRRdZrGnepUuXjvkazzzzjMVhGt327dstHjp0qDem6SJnn322xbVr1/bm5XLb+Mcff9zi2267LeF/p9fH66+/Pt84WfT801IQF198cdL/VjYL05P0/CiM1157zduOl06lKez6OXvllVe8edrCvKhgJQ4AAAAAAEAE8BAHAAAAAAAgAniIAwAAAAAAEAE5WxPnjjvusDhsdTtq1CiLJ06cmLZ9yjZ/+9vfvO0mTZrkO++dd97xtmkrnh0uv/xyi7Vd8QcffJCBvUG63Hvvvd62tlmNZ8mSJRZfdtll3pi2kcw1ej0MWw2fe+65Fg8aNKjAr7127VpvW2tvlCtXLqHXCPPGkRqxWryHtQRefPHFdOwOkqxTp07e9v/93/9ZrDUbnNu1zS6SQ1uE6/nWpUsXb56ec1q7SGvghB566CFvu27duhafd955+b6ec7t+F+YSrYsyZMgQb2zgwIEW7723/1O2atWqFserH5YMWgNQPzPa5tw55x5++OGU7gecu/POOy0uSE2ia6+91uLC3EdlEitxAAAAAAAAIoCHOAAAAAAAABGQM+lUuuzcOef+8Y9/WPzTTz95Yw8++GBa9inbJdoS8MYbb/S2aSueHapXr57vf9+wYUOa9wSpNnLkSIuPPPLIQr3GnDlzLJ4wYcIe71O2mDdvnsXaAtc55xo1amRxnTp1Cvza2kY39Oqrr3rbXbt2zXde2BIdyVGlShVvO0zp+MPy5cu97SlTpqRsn5A6rVu3jjn2/vvve9vTpk1L9e7kPE2t0riwwuukpgdpOlXLli29eWXKlLE4bIme7bSlc3hdO+KII2L+uzPOOMPiffbZx+L777/fmxerxENhabpz48aNk/rayF/37t0t1hS2MMVOzZ4929seOnRo8ncsTViJAwAAAAAAEAE8xAEAAAAAAIiArE6nKlu2rMVPP/20N1a8eHGLNRXAOecmT56c2h2DR5eLOufcjh07CvwaGzdujPkaupyydOnSMV/j4IMP9rYTTQfTJZ933XWXN7Z169aEXiMbtW3bNt//Pnz48DTvSW7Spb3xOjTEW8bft29fiytXrhxznr7+zp07E91FT7t27Qr173LZ9OnT842TYfHixQnNq1+/vrc9a9aspO5HrjrppJO87VjncNjdEdEUXoe3bNli8RNPPJHu3UGKvfHGGxZrOlXnzp29eVpugFIPifnkk0/y/e+afuycn07166+/Wvzyyy978/r162fxrbfe6o3FSnNFajRt2tTb1mvjAQccEPPfaZkO7UblnHM///xzkvYu/ViJAwAAAAAAEAE8xAEAAAAAAIgAHuIAAAAAAABEQNbVxNFaN6NGjbK4Zs2a3rxFixZZrO3GkX4zZ87c49d48803ve0VK1ZYXLFiRYvDfONkW7lypbf9yCOPpPTvFSXNmzf3titVqpShPYFzzr3wwgsW9+zZM+Y8bV8br55NorVuEp3Xp0+fhOYhM7SmUn7bf6AGTmpoTb/Q2rVrLX7qqafSsTtIAa3NoPcpzjm3evVqi2kpnn30e1K/n88//3xv3j//+U+LBw8e7I0tWLAgRXuXnT766CNvW+/PtSX1VVdd5c2rU6eOxaeddlpCf2v58uWF2EPsTlg78cADD8x3ntYUc86vO/XZZ58lf8cyhJU4AAAAAAAAEcBDHAAAAAAAgAjIunSq2rVrW9y4ceOY87R9tKZWIXnC1u3hMtFk6tSpU6H+nbYVjJcG8t5771k8ZcqUmPPGjx9fqP3IBh06dPC2NbXxq6++svjTTz9N2z7lsqFDh1p8xx13eGPly5dP2d9ds2aNtz137lyLr776aos15RFFT15eXtxtpNbZZ58dc2zZsmUWb9y4MR27gxTQdKrw/BoxYkTMf6cpBIcccojF+rlAdEyfPt3i++67zxvr1auXxY8++qg39pe//MXibdu2pWjvsofeizjnt3m/6KKLYv67li1bxhz77bffLNZz9u677y7MLiIfer278847E/o3AwYM8LbHjh2bzF0qMliJAwAAAAAAEAE8xAEAAAAAAIgAHuIAAAAAAABEQORr4lSvXt3bDlvI/SGsCaFtdZEaF1xwgbetuYz77LNPQq9x9NFHW1yQ9uAvvfSSxUuWLIk57+2337Z43rx5Cb8+fleqVCmL27RpE3PeW2+9ZbHmECN1li5davHFF1/sjbVv397iW265Jal/V9t2Oufcc889l9TXR3rst99+Mceov5Aa+r2o9f1C27dvt3jHjh0p3Sdkhn5Pdu3a1Rv761//avHs2bMtvuyyy1K/Y0ip1157zdu+5pprLA7vqR988EGLZ86cmdodywLh99att95q8QEHHGDx8ccf782rUKGCxeHvif79+1t8//33J2Ev4Zx/PObMmWNxvN+Oeg7osc1mrMQBAAAAAACIAB7iAAAAAAAAREDk06m0Za1zzlWrVi3feePGjfO2aZeafj179tyjf9+lS5ck7QmSRZfyb9iwwRvTtuxPPfVU2vYJuwrbuuu2pqCG19N27dpZrMezb9++3rxixYpZrEtfEV1XXHGFt/3jjz9a/NBDD6V7d3LCzp07LZ4yZYo3Vr9+fYsXLlyYtn1CZnTv3t3ibt26eWP//e9/LeZczC5r1qzxtlu1amVxmMpz1113WRym3GH3Vq1aZbHe62jrduecO+GEEyx+4IEHvLHVq1enaO9y2+mnn25xlSpVLI73213TTDXlOJuxEgcAAAAAACACeIgDAAAAAAAQAcUKklZUrFixIpGD1Lx5c4tHjhzpjWlFa9W0aVNvO1yqXNTl5eUV2/2s3SsqxzBHTc3Lyzt+99N2j+OYOZyLWYFzcTeGDx/ubffu3dviMWPGpHt38pXN52LlypW97YcfftjiqVOnWpwF3d9y9lzUe1ntNOScn/L6wgsveGOauvzLL7+kaO8KJpvPxaIi7L574oknWtysWTOL9yClOWfPxWySDefijBkzLG7QoEHMeb169bJY0wuzQELnIitxAAAAAAAAIoCHOAAAAAAAABHAQxwAAAAAAIAIiGSL8RYtWlgcqwaOc84tWrTI4s2bN6d0nwAAyBbachXp98MPP3jbV155ZYb2BKkyYcIEi7WlLpCfCy+80NvWuiF16tSxeA9q4gBFQpkyZSwuVuzPEj9hS/d///vfadunooiVOAAAAAAAABHAQxwAAAAAAIAIiGQ6VTy6vPCMM86weP369ZnYHQAAAAAotJ9++snbrlmzZob2BEit3r175xs/9NBD3rwVK1akbZ+KIlbiAAAAAAAARAAPcQAAAAAAACKAhzgAAAAAAAARUCwvLy/xycWKJT4ZSZWXl1ds97N2j2OYUVPz8vKOT8YLcRwzh3MxK3AuZgHOxazAuZgFOBezAudiFuBczAoJnYusxAEAAAAAAIgAHuIAAAAAAABEQEFbjK91zi1NxY4grupJfC2OYeZwHKOPY5gdOI7RxzHMDhzH6OMYZgeOY/RxDLNDQsexQDVxAAAAAAAAkBmkUwEAAAAAAEQAD3EAAAAAAAAigIc4AAAAAAAAEcBDHAAAAAAAgAjgIQ4AAAAAAEAE8BAHAAAAAAAgAniIAwAAAAAAEAE8xAEAAAAAAIgAHuIAAAAAAABEAA9xAAAAAAAAIoCHOAAAAAAAABHAQxwAAAAAAIAI4CEOAAAAAABABPAQBwAAAAAAIAJ4iAMAAAAAABABPMQBAAAAAACIAB7iAAAAAAAARAAPcQAAAAAAACKAhzgAAAAAAAARsHdBJhcrViwvVTuC+PLy8ool43U4hhm1Ni8vr3wyXojjmDmci1mBczELcC5mBc7FLMC5mBU4F7MA52JWSOhcLNBDHAAFU6zYn9fSvLy8pRncFeyBP45jXh7faVmCcxHIEL4XgSKJcxEoGhI6F3mIA6QQP/qzA8cRAJKD6ykAAHuGmjgAAAAAAAARwEMcAAAAAACACOAhDgAAAAAAQARQEwcZoYUNS5QoEXNMc+f1vzvn3N57//nx3bFjhzf2888/J2U/AQAAkiHW/Q0AAAXBShwAAAAAAIAI4CEOAAAAAABABJBOhbTZa68/nxmeeuqpFjdv3tybt2HDhnzjMO2qTp06Fn/55Zfe2Icffmjxtm3bCrnHSLcwZU6x9Dyz9Njoueycczt37rSY4wQUfXo+h9ddPZ9RcMWLF7e4UqVK3pimfq9du9Zi3nMAei3WkhHO+deVWCUjuP/KLazEAQAAAAAAiAAe4gAAAAAAAEQAD3EAAAAAAAAigJo4SJkwn7NNmzYWP/LIIxb/+OOP3rxvvvnG4o0bN1pcs2ZNb94xxxxjcb169byxqVOnWvzdd98VZLcRSHadmvD19tlnH4tLlSrljf32228Wb968eY/+LgpOz+GKFStarMfFOefWrVtnsdZ8QGaE55geRz12ha3Doa+vefqhX3/9tVCvj8SFx1rrVe27777e2AEHHJDvmF5bnXPup59+sjg815E//e7q0qWLxS1btvTmvfvuuxYPGzbM4lTUxNHzvmTJkt7Y1q1bLeYYxxeeY7pNLaPsp8d7v/3288b0HNN7n/C7T78nw+ty5cqVLW7Xrp3FDRo08OYtXrzY4ueff94b++N3FPdfuYWVOAAAAAAAABHAQxwAAAAAAIAIIJ0KSaXLDlu0aOGN3XfffRbrkm9dXuycnwqlS1VbtWrlzdN0qnCJY7wUIKSfHg9Nn3LOX0p6+OGHe2OaCrdw4UKLSdNIjbB1uJ5jHTt2tHjKlCnevI8++shilvNmhi7Rrlu3rjembY6nT59usbY4ds5Pq4iXsqh/q0aNGt6YXrOXLFnijf3yyy8xXxOJi5fOpmk9xx13nDd26qmnWqzH/oMPPvDmbdq0KSn7mc3C1uEPPvigxW3btrV45cqV3rw33njD4mSnBYdpGpdffrnFHTp08MZ69epl8fjx4y3mHP2dnmMHHXRQzHmaekiad3TFO97nn3++xZdddpk3Vq1aNYv13kdLQTjnXIkSJfKNw79Xrlw5i8NUvXnz5lncr18/b4zPXm5iJQ4AAAAAAEAE8BAHAAAAAAAgAjKaThUuA9bq+WHKxc8//2zx9u3bLS5sZXhNGwhTCHQCUcM+AAAfW0lEQVSpmy5NDpfAaUeHsLtDrlas1+4X119/vTdWpkwZiz///HOLhw4d6s1bvXq1xVr5Xf+9c85dfPHF+f5d5/xjpcskWXJYcMl4z/QYhMeqWbNmFh911FHe2KhRo/b4byM+vQ6HaTiPP/64xZrqdtZZZ3nzNJ0xTM3Q5ea5el1MFT122hGna9eu3rwVK1ZYrCmKGzZs8OYl2qVGv59PO+00b0zTI//zn/94Y/q3uRYXnr53YerwIYccYrF2hHTOuebNm1s8ceJEi7dt2xbz9fEn/e56+umnvbHWrVvn+2/ee+89b3vu3LkWJ/u7VVMxnHOuW7duFh955JHemF7D9X6MdKrf6bHu3r27N6bvuV7jwhQazqPU0WMQ/obTbZ0XdszVY9y4cWOLb7zxRm/eySefbHGYapXo7wu99wm/Z3Vb47Bzr94Px0qF5jP3u3glNcJnD/p50eMUhbINrMQBAAAAAACIAB7iAAAAAAAARAAPcQAAAAAAACIgozVxwhonF1xwgcWnnHKKN7Z+/XqLtb2ttkt1zq+do/mO5cuX9+Y1atTIYs3hD7c1v1BrOzjn3OjRoy3+8MMPvTGtNZBLOYpai0Zr2zjn3LRp0yzW3M6wnpC26Yv33mleo9ZTcm7X3Fdkluanhq1Zzz77bIvDfOMRI0akdsdylNY00TbijzzyiDdP88T1GGoNHOecu/POOy3WuhvO+TUhtA7Hli1bvHnUy9m9MM9bj8+9995rcZjzPWfOHIvXrFljcZjzneh3le6Hfpc651zDhg0t/uSTT7wxrYmD1KhVq5bF4bmoNf60Nkt4b8O5+Luw1kanTp0sjlUDxznnBg8ebPEDDzzgjWkti2S8z3ouNmjQwBurUqWKxeG5Pnv2bIvDmki5Su8br7vuOotvvfVWb97WrVst1u+xt99+25unvwMKe61F/vRzr3XAnPM/91pnUb8vnfPr/On3VvjbVH9fhOesnjv6WQjvb/T3UDj2zTffWLxgwQKL9TeTc/5vX/2tm+30fiasqXnggQdarPel4byyZctaHH5e9Dq/bNkyi5csWeLN0xpFYe2wTH1nshIHAAAAAAAgAniIAwAAAAAAEAEZzTkJU16OOOIIi3WJv3PO7b///hZr+kW4DFhfU5dPhe3B9913X4vDJeq6zFGXQIZLTjUl4bPPPvPGwtatuWLTpk0Wv/jii96YLnvTVozhMrRYS+fq1avnzdPPRLg8UY+3LpVLtIUukkvPsWrVqnlj2vo0TK3TbZYfF0y8tu7aXvb222+3OGxDq+eYnjt6/XTOPzc1ncM55y699FKLJ0+ebPFjjz3mzZs0aZLFubRUuCDCdMPLLrvM4oMPPthiXXbtnHNvvPGGxZqaXNjroX62DjvsMG9Mv3c1NRapEabONWnSxOLq1at7Y5pCo/cs27dv9+Zxrf2d3rM459yVV15pcXhN1Tbdmtqo6YvOJf+91fub8L5Z74MWLVrkjY0bN87iXL0vCtOCO3ToYPHdd99tsV5bnfN/C/To0cPi008/3Zs3cuRIiz/99FNvbOnSpRZHoZVxUaO/9TRlyjnnOnfubLGmSYW/OfXaqdfA8Peb/s4Mz2ctpaHxt99+683Te9nwe1Hvd/SzEP42yubrcpi6qqm/J5xwgsXnnHOON0/PTU1Z03vX8PXD5wH6Gvo5CH+PzJs3L9/YOedmzpxpsR5PTb10LvFyIYliJQ4AAAAAAEAE8BAHAAAAAAAgAniIAwAAAAAAEAEZrYkT5h2+//77Foe1bmrUqGGx5sqFbb5Kly5tseathjmnuh3mpWnepOaUhzl2mi9N+8Df6fGYNWuWN6b5p5qfGNYk0lpD2gLwzDPP9OZpXQ5t/ZbfNjJLj7G2f3TOuXLlylms9Tqc2zUnFYnT80Nr4Djn12zQfPIwZ1xzsvUYxqtjFb6Gbrdo0cLiChUqePNuuukmi8MaY7l6PXXOf29btmzpjen7uXDhQov1+DrntxhPRv0LrXujteyc84+3tlN2LrePY6qEtVnat28fc2z8+PEWa7v3XK2Jsjs1a9b0trVmWFhHqFevXhbr5z7Vn3lthxy2lP/hhx8sfvrpp72x77//PqX7VVTp9+IVV1zhjWk7eG1DHB5rvS/R3wFt2rTx5unxGDZsmDem1+hcraFZEGHtL62917VrV29Mfy9OnTrV4v79+3vztC5RvJp/2mI8/G2hv1Uz1WY6qvReoXLlyt6Y1vu75JJLLA7rlK1atcpirauo32/O+fVywpqLWtOxUaNGFh933HHevHPPPTfma2hNHK2P9s4773jz9DOXjJqBrMQBAAAAAACIAB7iAAAAAAAAREBG06nC5Ui61FeXIznnL+XX5anhUlWdpyk78eaF7ca0BbIueWzatKk3T9tas0x8V+HSwlipGWH6habXaMvHsP2xtm6L1+KdJY6Zp+eHpsuFwqWqmhKprxGm4HH+7fqe6HLw7t27e2OapqhLhfX9ds5fKqxL87VVsXPObdq0yeKvv/7aG9MlqZoSWadOHW/eNddcY7Eugc5vv3KJLh/WZcXO+ekyb775psVz58715ul3bWHPFf0+Pfnkky2uWLGiN0+XN4fpkUgOPdfD9rqa3hYea11uHt5/4Xf6OY/XzjZ8/3SZfDKE13Olqf3a9rx27drePL0WjxkzxhvL1RQ6TQW9/PLLvTG91uq1a/jw4d68GTNmWFy3bl2LwxbjmtZzxhlneGN9+/a1eOPGjRZzv/onPQf0d4Fzzl100UUWh5/7gQMHWvzWW29ZTHp+0aJpa82aNfPGWrdubbHeY4S/EfReZ/DgwRYvW7bMm6f3qGEak34v6j1qt27dvHmVKlWyWO+vnfO/N9atW+diSfb5zUocAAAAAACACOAhDgAAAAAAQARkNJ0qXOqrHZ7Cbk+pFC5b1Ur0S5Yssfikk07y5uk+hl2yEJ8ee+025pxzXbp0sVjTqcJ58+bNs1iXTDrnp1qRapN5utQwrC6v51GYfqFjsVIqw7FQrhz/8D3QtNBjjjnGG9Pl+Lq0dNGiRd487aihS5TDyv96nMJl+pquddttt1l88803e/MaN25ssXZccS63OqmEXTj0fQk7QWlHKu28EXZTScY5oEufdSl7eD5rCgfL11NDU1I7d+7sjeky7/C8Wbx4scWkbeRPz7/wfNPzKHz/NK1N7xvDc0CPnf6t8LzX+52wW44u82/VqpXF4ffnoEGDYo7lKj0/wmvXypUrLX7jjTcs7tevnzdP0/U1xS48htrdNuzG2LBhQ4u1e2Bhf0vEuz+Kqv3228/i0047zRvT8gphqiApVNGg18KwO5Wm0Ov9Zlhq5eOPP853XtjxTc+r8NqtKVoah2n88Z5LrFixwuJx48bl+9/z+9t7ipU4AAAAAAAAEcBDHAAAAAAAgAjgIQ4AAAAAAEAEZLQmTlER5o9qzpq2cA1z2b755huLtRUvdk/zd4899lhv7IYbbrBYa2NoizjnnBs6dKjF8+fP98bI9888PcYlSpSw+LDDDvPmaV5sWNdFa+noGDVwdhW+J9raW9uqhnOXL19u8bXXXuvN01bfYZ2VROl5q3Vbwr+lbSSPPvpob0zbm2f78dUaQs4517ZtW4vD4zhhwgSLta1l+B4l4z3T/dL6H+Frjx071mLaWCePnrNa1yOsFaH0HsU559asWWNxtp9HyaCtn53z6yqEdWpuvPFGi/WYhPcthx56qMUHHXSQxfpdl9+2Ovzwwy3We52RI0d687QVdthWN1eOf/i9qOdOeAz1e2bUqFH5/nfn/PdSY61R5lz8Nu5aI0fvgQp7nLLleO69958/S7Vu0NVXX+3N0/dp8uTJ3tiWLVtStHfYE+G5qLUZ9Z7COb8mmF53w5pRWktHaz9qzVTn/Gt5eK7UqVPH4jPOOMNivScNhb/5p02bZrHWBQzvgZJ9nrISBwAAAAAAIAJ4iAMAAAAAABABpFO5XZet1q9f3+LWrVtbHLYPnDRpksXpbImeDXRp/r333uuNVapUyWJt9zZ48GBvnqZmhMsns2VpabbQ463H1zl/OXjYFpDjmLjwOqZLkXW5tnN+atQjjzxicbgsOd5y8MLYunWrxeH+ajvRsLXv6NGjk7ofRVn4PaMtbMPvGb3uJftcCZc+axqIpiSEbTjffvvtlO1TLtPjocdCU46d85d5a0qIc/7Sbo5N/vQc03sM55xr2bKlxVWrVvXGatWqZXG1atUsDr/T9Lqn10NNrXLOv2aHKVn6mtpi97XXXvPmacvsZF/LoyL8ntE0jfDYLFu2zGI9V8Jrsp47en0O24hre2tNd3XOP081hSi87ubaearnQceOHS2uW7euN+/LL7+0ODyO2dhuPRuEx0LPzTCNPFbJhPAc0/OvRo0aFuv12Dk/lTgs6dCiRQuLtXW9Xiuc81uYaxtx55wbMGCAxXodSfV1l5U4AAAAAAAAEcBDHAAAAAAAgAjI2XQqXapVrlw5b0zTCzT1Q5fvOed3bmHJ3u7pe64dqE4++eSY/0aX5j/xxBPe2KpVqyymG1XRo0uQdYlikyZNvHl67DR9zjl/KWK8c0zHcvVcDJd8a8X9cEm5Lj8ePny4xale+qnX07AziKYPaFfAXBMeA12SH17nypcvb3Hp0qUtDlOcYp0T8ZY3h5+n5s2b5zs2e/Zsb17YKRDJocdGO3kceOCB3jz9Xpw1a5Y3pseblIP86XsxZ84cb+yWW26x+MQTT/TGNB10yZIlFocdi/T19TrXvn17b16zZs0sDtPFtStdv379LNbl/s75qWG5eow1Vck5P10nvNbq9VS7Aoa/ETQ1SjvihGkac+fOtTjscKXnn6aShNdu7cKUjccwTJvR46Mpi+F1rmnTphbrbzbnnHvooYcs/uqrryyO1/krXvfTePeX2XhM0kWvaytWrPDG9H5Gr61hdyq9b9R0Kk2zcs5PQQ5T8/SzFe/6/8wzz1g8ZswYb0zTIxP93ZIMrMQBAAAAAACIAB7iAAAAAAAARAAPcQAAAAAAACIgZ2viaL7cPffc441prrPm7D388MPevI0bN6Zo77JTzZo1Lf7HP/5hcVgb4/PPP7f4gQcesHj16tXePHJRizY9rtdcc43FVapU8eZprvjMmTO9Mc0P13ogHPtdhe+J1gIIa6l8++23Fod1iJJNc5a7detmcZjjrvUbtDVurgnbiGte9kknneSNabvNs846y+IPP/zQm6f1VPT1tcWxc36NjrDlcZcuXSzW87JPnz7ePG1fj+TRuhnnn39+vv/dOf++JKyRoteBWC1cneP6+ofws6y1aL744gtvTN9Prb0Rr16fXhvD9/zwww+3WOscOefciBEjLNZ2tuG1A7t+zrV2Rfg9U7FiRYvbtWtncVhDQ6/JWrPsgw8+8Obp74ewLp3W+dCW9OEx1O/nXDi++t0yZcoUi8PamWXLlrX4zDPP9MYaNGhg8fTp0y0Oj4/+ptDvu/B7UdvNh5+ZTZs2WaxtrMPzXj93YV2XXKXv3TvvvOONaYtw/dyvX7/em6f3kfqZ0FpVzjnXuHFji7X2lXP+ubl48WKLn3rqKW/e+++/b7F+JpzL3HcmK3EAAAAAAAAigIc4AAAAAAAAEZAz6VQlSpTwti+77DKLL730Um9Ml0Vpi+tx48bFnIddha0de/bsabEugQtby1177bUWh8uIER26tFHbpYafi6VLl1qsS1+dy43lw8kStkvVJcHh2Lx582KO7akwPVJbtV5yySUWh8vLdbnxpEmTvLFcutaGx0OX94YpvJpycd1111l86qmnevP2339/izVFRFshO+efs2G625FHHmmxXpfHjh3rzculY5VKYRqIpiOfcMIJFofnkbY1Dr8/Y7XK5ZglRs/NsBV0YVq26zxtW+2cf8+6du1ab2z27NkW8x0ZX3g9/frrry1+6aWXvLGWLVtarOdYqVKlvHl6DR09erTFmqbsnJ9Wp9dg55w755xz8o3D1xg5cqTFYSpJNpy34f+GDRs2WDxw4ECLixcv7s3r2LGjxfo96JyfFqdpxmE6sqbz6DEN0yj1b4fn/SGHHGLx8uXLLdbPhXPO9e3b1+LwXM9Veu3SVvDhtqamhWlq+v1XpkwZizVd0Tnn2rdvb7GmsTrn31c9+eSTFg8fPtybF6ZQFQWsxAEAAAAAAIgAHuIAAAAAAABEAA9xAAAAAAAAIiCra+JojvIRRxzhjd10000WhzUcNAf173//u8W0Ti0YraHgnF+nQXML77rrLm+etm9EdIQ1HI499liLta14mNOqbfvCmh9IXJhbHl7XlNZb0PzgROvjhHWNtB2ktqJ2zrkrr7zS4oMPPtjisJbDZ599ZrG2zc112o40bAev55Xmg9erV8+bp7n/WmMnrHujn4XatWt7Y5pjrtdorWGA5AnPMa3dV7VqVYvDPH2txaDH3bn47a6xZwpTn0S/M8N6HXXq1LH4k08+8cbC44rYtC6Nc36LaL3Xd85vaa21VA477DBv3qeffmqx1ieK9xshbFv95ZdfWqw1A8PPgdbwCa+12VATJ6Tfd1ovU2uVOOfcu+++a3Hnzp29sW7dullcoUIFiw844ABvnrYV12MXnl96jT300EO9sXLlyllcvXp1F8uLL74YcyxX6ee3sG3X9TtNz3U9f53zj1v4PfjRRx9ZPGDAAIuLYg2cECtxAAAAAAAAIoCHOAAAAAAAABGQdelUujxVl7n95z//8eZVrlzZ4tWrV3tjvXr1sjhcvo749P2/6KKLvDFdur9582aLtSVq+BrJFrYp1PSBMP1El7Pr8ruwxaAu4Yu3XD0bl76q8L3VtpmaiqHH3jnnxowZYzHL/QsvPG90qXDYhlhTZTTWVBvn/HNA03VOP/10b56mTB111FEx90OF191+/fpZHIVlrKkSXie0TfT48eO9senTp1v83XffWfzNN99487T1qZ5/pUuX9uadeeaZFp988snemLbZ1Tjbr2vppOdwpUqVvLHzzz/fYr3Whi2JNfUml8+jdCvMfYuef9oC1zn/fmTevHneWKJpr9iVXq/CVCtN3/nggw8sDs9FvSbrORbvWhgeM71er1mzxmJNQ3fO/x2Tynvjoiheus38+fMtfvTRR72xIUOGWHz77bdbrCUdnPN/B+rrh/dBmsYW3t/o8dFjrOnhzpECmSp6b6tpieE9qt7Lhvee+vkJf98VdazEAQAAAAAAiAAe4gAAAAAAAERA1qVT6TLvZ555xuImTZp483QZpVajds65WbNmWcyy1YLRtJmzzz7bG9OloLoE9YwzzvDmadeaBQsWxPxbemzCZab6OdDq9C1atPDm1a9f3+LDDz/cG9Ml65qCoN0InPNTHD7//HNvTD9nUVumV1Bh2oymZujxWbp0qTdPlyaTmlF4JUuW9Lb3339/i8M0NT0nevToYfH//vc/b54uHdZzR7vjOOfcIYccYnGYVqfH/qeffrJ42rRp3rwvvvgi5v7mkvA7Z8mSJRb379/fG9Nril5Tw9eIdV6F3U4mTpxo8S233OKNaeqppheExxuFp0u+27Zt643p0n/tpDJw4EBvni4V53qaOmH3MN2O977r8n/tRKQd/pzz7znC9Eikhn7vaIpTvK5QiZ5j4Ty9dmsHqrCrq153w89cLv8+iZcWp+mHt956q8WdOnXy5umY3qesXbvWm6efi3hdP3/44QeLX3/9dW8s3EcUTngO6DVU3/OwE5l2h3vggQe8Mf28RO07k5U4AAAAAAAAEcBDHAAAAAAAgAjgIQ4AAAAAAEAERL4mTpiPr/VVzjrrLIvDFruag9q7d29vTPPNUTBaayNsy6j5u1o755JLLvHmaWtqraFRokQJb56OhfVAtHWntkYuW7asN0/3I/wsaW0ezZHVf+Ocn9sc1svJ9hb1mkfcsGFDb+ywww6zWI/9pEmTvHlhvjkKJ/xs63UszMfWtpitWrWyWPOLnXPu4IMPtlg/92Fesn4Owjx9re0wbtw4i//1r39589avX+8Qv3ZCWFdrT/O3w2OlOf0bN26M+bdyuRZDsum9idaW6tChgzdPv+O+//57i7UVsnP+9xaSS69z4f1CrOtjeL+gNTVatmwZc57WZNF6DkgPvcbFq9FW2Guwvqa2tJ4zZ443Tz8vBx54oDem3+u5XEcuHr3/ePPNN70x/Z1w0UUXWVyzZk1vnl6Xy5cv743p9XbQoEEWh23KUXh6Pe3cubM39vTTT1usxylsSf/YY49Z/N///tcbi/J3JitxAAAAAAAAIoCHOAAAAAAAABEQ+XSqsN3bpZdearEulQtTNrp162bxunXrUrR3uUeXfIdtMXV5my5FDltTV6lSJd/XC9OpdPlouLxf2+1qHKaVaLpTmKqgqR+6ZH3mzJnePG2RrX/Luei1qysoPSbdu3f3xnQJpC4Nf+WVV7x5pC8mx5YtW7ztTz/91GJtN+6cn/aoKVNhW0Ztb5ooXb7snHNz5861+P7778/3vztHik4s6byG6PU23tJ9vQaG103sStNwQnqO1a1b1+I6dep48/T9X7BggcXLli3z5mX7d04mxWtrrNcv/e4Lj72mslatWjXmPE2hCu+R9P4pyqkAUZGKc0pfU9NYw3RzFZYN0FTMwrQ9zzVhWuKECRMs7tixo8W1a9f25unvzLA0h5Z1ePXVVy2mpfie0euhfhf26tXLmxcrheqJJ57w5vXs2TPfeVHHShwAAAAAAIAI4CEOAAAAAABABPAQBwAAAAAAIAIiXxNH8+Gcc65Ro0YWa15o2FpOW0GTP5o8y5cvt7hHjx4x52n+eFh7oUaNGhYfffTRFtevX9+bpzmnYStvrRmwcOFCi7U1a/jvVq5c6Y1prSTqdfxJc1W1jXjYllHfv969e1s8bdo0b56+t5yLhRfW9rrvvvssfuutt7yx1q1bW9ypUyeLtY6Yc86VKlXKYq1BFeZ76/bHH3/sjT377LMWz5o1y2LOqaJHayeFtY0WLVpkcd++fS0O64ChYLSuWL169SwOay9oy/epU6daHNYU0+sz19PUCVs6x6vRp7SejX5/hnXLypQpY3Hjxo29Ma03uGnTppj7pMLPAp+NzNL3X4/h0qVLvXn6OQg/I1p7SV+P79b8hefH/PnzLX7vvfcs1rqczvl1A8N6Klp78LvvvkvKfsL/XtRaihUrVvTm6THV3/kPPfSQNy/ROjj6/RmvDmtYiyxT11NW4gAAAAAAAEQAD3EAAAAAAAAiIJLpVLrM+JxzzvHGDj30UIu1ndwLL7zgzWO5YWroEvwvvviiUK+hy9l06bEuHQ2Fx1OXvWnMkuI9p8dHUyn69evnzVu/fr3Fo0ePtpiW4qkRLhXW1pcTJ070xr7++muLx48fb/FJJ53kzStfvrzFuuRbW6I657cLD897TVnkfCtawmtqs2bNLN6wYYM3NmzYMIvnzZtnMcd09/Q9CltJayril19+afE777zjzdPl2wMHDrQ4TGfjeGSeHoNwGb8eL20drq3mnfNTWxs2bOiNaeqH3udyfxNN+t0dLz1S05ud81tf6z1weC/A5yB/W7ZssXjw4MEWb9u2zZtXq1Yti1evXu2N6bU4m1pXp1v4vahtxfV3fphmvHjxYovvvPNOiwv7O0PvicLrrl5rtUzHnvy9PcVKHAAAAAAAgAjgIQ4AAAAAAEAERDKdSpedXnjhhd6YVpPWZVbaWQPpUdglnPrv4nXEQWboMVm1apXFAwYM8Obp8v94XTOQeuH7r51uPvzww3zjeFienR00Xc45f/mwdsBxzrlRo0ZZTEeqwgvPHX0vp0+fbvGcOXO8eXoO67J9rq1FW3h8vv32W4tfeeUVi5s3b+7N08/CoEGDvDFN6dDvWa7L0aHHKl6nVf387LfffjFfI5H/Dp++t9pZt0+fPt68eB3/wi5FKJwwTapJkyYWa9pgmOqmXZBXrFixx/uhxzc8tvG6U2UKK3EAAAAAAAAigIc4AAAAAAAAEcBDHAAAAAAAgAiIZE0cbbNXpUoVb0zb6mrLOG0NBiA5ikpeKAqP/Pncovn9xYsX98a0Do7WlHPOuSVLllhMHZbkiZWDz7U1O+m9aL9+/Sx++eWXvXna/jhsXcw1O7voua7H3Tn/2GvNz/Df8ZnYM/FqoSD1ws/v+vXrLV65cqXF06ZN8+YNGzYsqfvx22+/WRzWpdOxovIZYSUOAAAAAABABPAQBwAAAAAAIAIimU6ly65GjBjhjWnr3Oeff95iXQYFAEAu0u/PNWvWeGNDhgyxePv27d6YtsJm6T5QOHruaPo/cot+DjQOU1W1/Xh4TY71ekDUhJ/7sWPHWnzttddaPGXKFG9evHOiMPQ8SvZrpwIrcQAAAAAAACKAhzgAAAAAAAARwEMcAAAAAACACIhMTZxYbVFfeeUVb57WxAlb9QEAgN+FeeibNm2KOUZbcQDInLDujf4uArLJ1q1bLZ4wYYLFUahTk06sxAEAAAAAAIgAHuIAAAAAAABEQEHTqdY655amYkd2R5cRrlu3Lt84i1VP4mtl7BiC45gFOIbZgePo/Pa1EcQxzA4cx+jjGKZBmE6VgrbiHMfoy4pj+Ouvv+Yb55CEjmOxFFwEAAAAAAAAkGSkUwEAAAAAAEQAD3EAAAAAAAAigIc4AAAAAAAAEcBDHAAAAAAAgAjgIQ4AAAAAAEAE8BAHAAAAAAAgAniIAwAAAAAAEAE8xAEAAAAAAIgAHuIAAAAAAABEwP8Dt4V95GFWjL4AAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 1440x432 with 20 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "n = 10\n",
    "plt.figure(figsize=(20, 6))\n",
    "for i in range(n):\n",
    "    # 原图\n",
    "    ax = plt.subplot(3, n, i+1)\n",
    "    plt.imshow(X_test[i].reshape(28, 28))\n",
    "    plt.gray()\n",
    "    ax.get_xaxis().set_visible(False)\n",
    "    ax.get_yaxis().set_visible(False)\n",
    "\n",
    "    \n",
    "    # 解码效果图\n",
    "    ax = plt.subplot(3, n, i+n+1)\n",
    "    plt.imshow(decoded_imgs[i].reshape(28, 28))\n",
    "    plt.gray()\n",
    "    ax.get_xaxis().set_visible(False)\n",
    "    ax.get_yaxis().set_visible(False)\n",
    "    \n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练过程可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 175,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dict_keys(['val_loss', 'loss'])\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYsAAAEWCAYAAACXGLsWAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzt3Xl8XXWd//HXJ/t20yZpmqRJoQs06ULpTgFBkEVwAcQqVVBhHEHRAWdGR3TGdX7OOI6D6IgKjiAqgkwBwWEtiyiydRFq940uabqkTdvs++f3xzlN0zTLTdvbm+X9fDzuI/ee8z33fhJo3jnf7znfr7k7IiIivUmIdwEiIjLwKSxERKRPCgsREemTwkJERPqksBARkT4pLEREpE8KC5ETwMx+YWb/L8q2W8zs4uN9H5GTSWEhIiJ9UliIiEifFBYybITdP180sxVmVmdmPzezAjN7ysxqzOw5M8vp1P4KM1tlZgfM7A9mNrnTvplmtjw87rdAWpfPep+ZvRke+4qZTT/Gmj9lZhvNrMrMHjezMeF2M7Pvm9keMzsYfk/Twn3vMbPVYW07zOwLx/QDE+lEYSHDzQeBS4BJwPuBp4CvAKMI/j3cAmBmk4AHgM8D+cCTwO/NLMXMUoDfAb8CcoH/Dd+X8NhZwD3ATUAecBfwuJml9qdQM3sX8O/Ah4EiYCvwYLj7UuD88PsYCVwD7Av3/Ry4yd0jwDTghf58rkh3FBYy3Py3u+929x3An4DX3f0v7t4EPArMDNtdAzzh7ovdvQX4HpAOnAPMB5KBO9y9xd0XAUs6fcangLvc/XV3b3P3+4Cm8Lj+uBa4x92Xh/V9GTjbzMYBLUAEKAPM3de4+87wuBZgipllu/t+d1/ez88VOYrCQoab3Z2eN3TzOit8PobgL3kA3L0d2A4Uh/t2+JGzcG7t9PxU4B/DLqgDZnYAGBse1x9da6glOHsodvcXgB8BdwK7zexuM8sOm34QeA+w1cxeMrOz+/m5IkdRWIh0r4Lglz4QjBEQ/MLfAewEisNth5zS6fl24NvuPrLTI8PdHzjOGjIJurV2ALj7D919NjCVoDvqi+H2Je5+JTCaoLvsoX5+rshRFBYi3XsIeK+ZXWRmycA/EnQlvQK8CrQCt5hZkpldDczrdOzPgE+b2VnhQHSmmb3XzCL9rOE3wA1mNiMc7/g3gm6zLWY2N3z/ZKAOaATawjGVa81sRNh9Vg20HcfPQQRQWIh0y93XAdcB/w3sJRgMf7+7N7t7M3A1cD2wn2B845FOxy4lGLf4Ubh/Y9i2vzU8D3wVeJjgbGYisDDcnU0QSvsJuqr2EYyrAHwM2GJm1cCnw+9D5LiYFj8SEZG+6MxCRET6pLAQEZE+KSxERKRPCgsREelTUrwLOFFGjRrl48aNi3cZIiKDyrJly/a6e35f7YZMWIwbN46lS5fGuwwRkUHFzLb23UrdUCIiEgWFhYiI9ElhISIifRoyYxYiMrS0tLRQXl5OY2NjvEsZEtLS0igpKSE5OfmYjldYiMiAVF5eTiQSYdy4cRw5wa/0l7uzb98+ysvLGT9+/DG9h7qhRGRAamxsJC8vT0FxApgZeXl5x3WWprAQkQFLQXHiHO/PctiHxcH6Fn7w3AZWlB+IdykiIgPWsA+LhAT4/nPr+dOGvfEuRUQGkAMHDvDjH/+438e95z3v4cCBoffH57APi0haMsUj01m7qybepYjIANJTWLS19b7w4JNPPsnIkSNjVVbc6GoooKwwwrpd1fEuQ0QGkNtuu41NmzYxY8YMkpOTycrKoqioiDfffJPVq1dz1VVXsX37dhobG7n11lu58cYbgcNTD9XW1nL55Zfzjne8g1deeYXi4mIee+wx0tPT4/ydHRuFBVBaGOGl9ZU0t7aTkjTsT7ZEBpxv/n4VqytO7B90U8Zk8/X3T+1x/3e+8x1WrlzJm2++yR/+8Afe+973snLlyo5LT++55x5yc3NpaGhg7ty5fPCDHyQvL++I99iwYQMPPPAAP/vZz/jwhz/Mww8/zHXXDc5VbvWbkSAsWtudTZW18S5FRAaoefPmHXGPwg9/+EPOPPNM5s+fz/bt29mwYcNRx4wfP54ZM2YAMHv2bLZs2XKyyj3hdGYBlBVmA7BuVw2Ti7LjXI2IdNXbGcDJkpmZ2fH8D3/4A8899xyvvvoqGRkZXHDBBd3ew5CamtrxPDExkYaGhpNSayzozAKYkJ9JcqJpkFtEOkQiEWpquv+dcPDgQXJycsjIyGDt2rW89tprJ7m6k09nFkByYgIT87M0yC0iHfLy8jj33HOZNm0a6enpFBQUdOy77LLL+OlPf8r06dMpLS1l/vz5caz05FBYhEoLIyx5uyreZYjIAPKb3/ym2+2pqak89dRT3e47NC4xatQoVq5c2bH9C1/4wgmv72RSN1SotDBCxcFGDja0xLsUEZEBR2ERKiuMALB+t8YtRES6UliESsMrojTILSJyNIVFaMyINCJpSRrkFhHphsIiZGaUFkRYpzMLEZGjKCw6KS2MsHZXDe4e71JERAYUhUUnZYURahpb2XlQa/6KSP9kZWUBUFFRwYIFC7ptc8EFF7B06dJe3+eOO+6gvr6+4/VAmfJcYdFJaadpP0REjsWYMWNYtGjRMR/fNSwGypTnMQ0LM7vMzNaZ2UYzu62b/eeb2XIzazWzBV32nWJmz5rZGjNbbWbjYlkrQGlBcPmsrogSkS996UtHrGfxjW98g29+85tcdNFFzJo1izPOOIPHHnvsqOO2bNnCtGnTAGhoaGDhwoVMnz6da6655oi5oT7zmc8wZ84cpk6dyte//nUgmJywoqKCCy+8kAsvvBAIpjzfuzdYnO32229n2rRpTJs2jTvuuKPj8yZPnsynPvUppk6dyqWXXhqTOahidge3mSUCdwKXAOXAEjN73N1Xd2q2Dbge6O7Wxl8C33b3xWaWBbTHqtZDRmQkUzQiTVdEiQw0T90Gu/56Yt+z8Ay4/Ds97l64cCGf//znufnmmwF46KGHePrpp/n7v/97srOz2bt3L/Pnz+eKK67ocX3rn/zkJ2RkZLBixQpWrFjBrFmzOvZ9+9vfJjc3l7a2Ni666CJWrFjBLbfcwu23386LL77IqFGjjnivZcuWce+99/L666/j7px11lm8853vJCcn56RMhR7LM4t5wEZ33+zuzcCDwJWdG7j7FndfQZcgMLMpQJK7Lw7b1bp7PSdBWTjILSLD28yZM9mzZw8VFRW89dZb5OTkUFRUxFe+8hWmT5/OxRdfzI4dO9i9e3eP7/HHP/6x45f29OnTmT59ese+hx56iFmzZjFz5kxWrVrF6tWre3obAF5++WU+8IEPkJmZSVZWFldffTV/+tOfgJMzFXos54YqBrZ3el0OnBXlsZOAA2b2CDAeeA64zd2PWM/QzG4EbgQ45ZRTjrtgCMYtXt64l5a2dpITNaQjMiD0cgYQSwsWLGDRokXs2rWLhQsXcv/991NZWcmyZctITk5m3Lhx3U5N3ll3Zx1vv/023/ve91iyZAk5OTlcf/31fb5Pb1dpnoyp0GP527C787Jor0lNAs4j6J6aC0wg6K468s3c73b3Oe4+Jz8//1jrPEJZYYSWNuftvXUn5P1EZPBauHAhDz74IIsWLWLBggUcPHiQ0aNHk5yczIsvvsjWrVt7Pf7888/n/vvvB2DlypWsWLECgOrqajIzMxkxYgS7d+8+YlLCnqZGP//88/nd735HfX09dXV1PProo5x33nkn8LvtXSzPLMqBsZ1elwAV/Tj2L+6+GcDMfgfMB35+QivsRmnh4UHuSeGAt4gMT1OnTqWmpobi4mKKioq49tpref/738+cOXOYMWMGZWVlvR7/mc98hhtuuIHp06czY8YM5s2bB8CZZ57JzJkzmTp1KhMmTODcc8/tOObGG2/k8ssvp6ioiBdffLFj+6xZs7j++us73uNv//ZvmTlz5klbfc9idQOamSUB64GLgB3AEuCj7r6qm7a/AP7P3ReFrxOB5cDF7l5pZvcCS939zp4+b86cOd7X9cvRaG5tZ8rXnuamd07gi+/u/X8EEYmdNWvWMHny5HiXMaR09zM1s2XuPqevY2PWDeXurcDngGeANcBD7r7KzL5lZleERc41s3LgQ8BdZrYqPLaNoAvqeTP7K0GX1s9iVWtnKUkJTMjPZO1ODXKLiBwS08WP3P1J4Mku277W6fkSgu6p7o5dDEzvbl+slRZms3zr/nh8tIjIgKTLfbpRVhhhx4EGahq1EJJIPGmethPneH+WCotuHLqTWwshicRPWloa+/btU2CcAO7Ovn37SEtLO+b30Brc3eh8RdTsU3PjXI3I8FRSUkJ5eTmVlZXxLmVISEtLo6Sk217/qCgsulGSk05WapImFBSJo+TkZMaPHx/vMiSkbqhumBmTCrI07YeISEhh0YPSwmzWaSEkERFAYdGjssIIBxta2F3dFO9SRETiTmHRg8OD3JquXEREYdGDsjAsNMgtIqKw6NHIjBQKslMVFiIiKCx6VVqYrSuiRERQWPSqrDDCxspaWttivqKriMiAprDoRWlBhObWdrbs00JIIjK8KSx60XnaDxGR4Uxh0YvTRmeRmGAa5BaRYU9h0Yu05ETG5WXozEJEhj2FRR/Kwmk/RESGM4VFH0oLI2yrqqeuqTXepYiIxI3Cog+HBrm1EJKIDGcKiz5o2g8REYVFn8bmZJCRkqhBbhEZ1mIaFmZ2mZmtM7ONZnZbN/vPN7PlZtZqZgu62Z9tZjvM7EexrLM3CQnG6QURnVmIyLAWs7Aws0TgTuByYArwETOb0qXZNuB64Dc9vM2/Ai/FqsZolRVEWLdbCyGJyPAVyzOLecBGd9/s7s3Ag8CVnRu4+xZ3XwEcNfmSmc0GCoBnY1hjVMqKIlTVNVNZq4WQRGR4imVYFAPbO70uD7f1ycwSgP8CvthHuxvNbKmZLa2srDzmQvtSqkFuERnmYhkW1s22aPtxbgaedPftvTVy97vdfY67z8nPz+93gdEqK8wGFBYiMnwlxfC9y4GxnV6XABVRHns2cJ6Z3QxkASlmVuvuRw2Snwy5mSnkR1JZs1NhISLDUyzDYglwupmNB3YAC4GPRnOgu1976LmZXQ/MiVdQHFJWGGHdbq3HLSLDU8y6ody9Ffgc8AywBnjI3VeZ2bfM7AoAM5trZuXAh4C7zGxVrOo5XqUFETbsrqWtXVdEicjwE8szC9z9SeDJLtu+1un5EoLuqd7e4xfAL2JQXr+UFkZoChdCmpifFe9yREROKt3BHSUNcovIcKawiNLpBVkkmFbNE5HhSWERpWAhpEzW7dIgt4gMPwqLfigt1BxRIjI8KSz6obQwwtaqeuqbtRCSiAwvCot+KCuM4A4bdtfGuxQRkZNKYdEPpboiSkSGKYVFP5ySm0FacoKuiBKRYUdh0Q+JCcakAk37ISLDj8Kin0q1ap6IDEMKi34qLYywt7aZvVoISUSGEYVFP2naDxEZjhQW/XRo1TwNcovIcKKw6Kf8SCp5mSma9kNEhhWFxTHQtB8iMtwoLI5BaWGE9btraddCSCIyTCgsjkFZYYSGlja2VdXHuxQRkZNCYXEMDk37oUFuERkuFBbHYFJBFma6fFZEhg+FxTHISEnilNwMTfshIsOGwuIYlRZE1A0lIsNGTMPCzC4zs3VmttHMbutm//lmttzMWs1sQaftM8zsVTNbZWYrzOyaWNZ5LMoKI2zZW0djS1u8SxERibmYhYWZJQJ3ApcDU4CPmNmULs22AdcDv+myvR74uLtPBS4D7jCzkbGq9ViUFmbT7rBxjxZCEpGhL5ZnFvOAje6+2d2bgQeBKzs3cPct7r4CaO+yfb27bwifVwB7gPwY1tpvZUWa9kNEho9YhkUxsL3T6/JwW7+Y2TwgBdjUzb4bzWypmS2trKw85kKPxbi8TFKTEli7U4PcIjL0xTIsrJtt/brl2cyKgF8BN7h7e9f97n63u89x9zn5+Sf3xCMxwTi9IIt1u3VmISJDXyzDohwY2+l1CVAR7cFmlg08AfyLu792gms7IUoLstUNJSLDQizDYglwupmNN7MUYCHweDQHhu0fBX7p7v8bwxqPS1lhhMqaJqrqmuNdiohITMUsLNy9Ffgc8AywBnjI3VeZ2bfM7AoAM5trZuXAh4C7zGxVePiHgfOB683szfAxI1a1HqvDa1to3EJEhrakWL65uz8JPNll29c6PV9C0D3V9bhfA7+OZW0nQlkYFut21XDOxFFxrkZEJHZ0B/dxyI+kkpORrDmiRGTIU1gcBzOjtFDTfojI0KewOE5lhdms312jhZBEZEhTWByn0sII9c1tlO9viHcpIiIxo7A4TroiSkSGA4XFcZpUcPiKKBGRoUph0dIIy+6DA9v7btuNrNQkxuams1bTfojIEBZVWJjZrWaWbYGfh2tQXBrr4k6Kukr4v7+H135yzG9RWpCtMwsRGdKiPbP4G3evBi4lmCr8BuA7MavqZBo5Fs5YAMt+AQ37j+ktygojvL23jqZWLYQkIkNTtGFxaAbZ9wD3uvtbdD+r7OB0zt9BSx0sveeYDi8tjNDW7loISUSGrGjDYpmZPUsQFs+YWYQuCxYNaoVnwMSL4LWfBmMY/dR52g8RkaEo2rD4JHAbMNfd64Fkgq6ooePcW6FuD6x4sN+HjhuVSUpigsJCRIasaMPibGCdux8ws+uAfwEOxq6sOBh/PhSdCa/8N7T376QpOTGBiaOzNO2HiAxZ0YbFT4B6MzsT+CdgK/DLmFUVD2bB2cW+jbDuyb7bd1FWGNGZhYgMWdGGRau7O3Al8AN3/wEQiV1ZcTL5Shh5Kvz5B/0+tLQwwq7qRg7Wt8SgMBGR+Io2LGrM7MvAx4AnzCyRYNxiaElMgrM/B+VvwLb+reSqaT9EZCiLNiyuAZoI7rfYBRQD/xmzquJp5rWQntvvs4uOK6J0J7eIDEFRhUUYEPcDI8zsfUCjuw+tMYtDUjJh3o3BuEXluqgPK8xOIzstSYPcIjIkRTvdx4eBNwjWyv4w8LqZLYhlYXE171OQlBZcGRUlM6OsUNN+iMjQFG031D8T3GPxCXf/ODAP+GrsyoqzzFEw8zpY8Vuo3hn1YaWFEdbvqiG4FkBEZOiINiwS3H1Pp9f7+nHs4HT2Z6G9FV7/adSHlBZGqGlqZccBLYQkIkNLtL/wnzazZ8zsejO7HngC6PNmBDO7zMzWmdlGM7utm/3nhzPYtnbt1jKzT5jZhvDxiSjrPHFyJ8DkK2DpvdAY3RVOmvZDRIaqaAe4vwjcDUwHzgTudvcv9XZMeHntncDlwBTgI2Y2pUuzbcD1wG+6HJsLfB04i6DL6+tmlhNNrSfUubdA00FYfl9UzSd1XD6rsBCRoSUp2obu/jDwcD/eex6w0d03A5jZgwQ39a3u9J5bwn1d59d4N7DY3avC/YuBy4AH+vH5x694Now7D179Mcy7CZJSem2enZZM8ch0hYWIDDm9nlmYWY2ZVXfzqDGzvvpmioHOy8+Vh9uiEdWxZnajmS01s6WVlZVRvnU/nXsr1FTAyuhyMpj2QzfmicjQ0mtYuHvE3bO7eUTcPbuP9+5uvYtoLxOK6lh3v9vd57j7nPz8/Cjfup9OuxhGTwlu0oviKqfSwgibK+tobh06M7iLiMTyiqZyYGyn1yVAxUk49sQ6NMFg5RrYsLjP5qWFEVrbnU2VWghJRIaOWIbFEuB0MxtvZinAQuDxKI99BrjUzHLCge1Lw23xMe2DkF0Mr/ywz6ZlhcEJl66IEpGhJGZh4e6twOcIfsmvAR5y91Vm9i0zuwLAzOaaWTnBneF3mdmq8Ngq4F8JAmcJ8K1Dg91xkZgM82+GLX+C8mW9Np2Qn0lyommQW0SGlKivhjoW7v4kXe7HcPevdXq+hKCLqbtj7wGObVHsWJj9CXjpu/DKD+DDPU+LlZyYwMT8LA1yi8iQMrTvwj6RUiMw929gze9h36Zem5ZqISQRGWIUFv1x1qchIQlevbPXZqWFESoONnKwQQshicjQoLDoj0ghnLkQ3rwfanu+r+PQtB/rtbaFiAwRCov+OvvvoLURlvysxyal4RVRGuQWkaFCYdFf+ZOg9L3wxt3QXNdtkzEj0oikJWmQW0SGDIXFsTj3VmjYD3/5dbe7zYzSAg1yi8jQobA4FqecBWPPgld/BG2t3TYpLYywVgshicgQobA4VufeCge2werfdbu7rDBCTWMrb5UfPMmFiYiceAqLYzXpcsg7vccJBi8/o4iiEWnc9KulVGjlPBEZ5BQWxyohAc75O9i1At5+6ajdo7JSufeGudQ3tXHDvUuobtQ9FyIyeCksjsf0ayCrIDi76EZZYTY//dhsNlXW8plfL9O05SIyaCksjkdyWnBX96YXYOeKbpuce9oo/uOD0/nzxn3c9sgKDXiLyKCksDhec/4GUrJ6nb78g7NL+IdLJvHI8h18f/H6k1iciMiJobA4XukjYfb1sPKR4OqoHvzdu07jmjlj+eELG/ntkp7biYgMRAqLE2H+Z4IV9V79cY9NzIz/94FpnD8pn688upKX1sdozXARkRhQWJwII0pg2gJYfh/U97xGU3JiAj++dhalBRFu/vUyVlXoHgwRGRwUFifKubdASz0s/XmvzbJSk7j3hrmMSE/mhnuXsEP3YIjIIKCwOFEKpsJpl8Drd0FL7wFQkJ3GvTfMo6G5jRvufUPrXojIgKewOJHOvQXqKuGtB/psWloY4a6PzebtvXV8+le6B0NEBjaFxYk07jwYMxNe+RG0t/XZ/JzTRvHdBdN5dfM+vvSw7sEQkYFLYXEimQUTDFZtgrVPRHXIB2aW8IVLJ/HoX3Zwu+7BEJEBKqZhYWaXmdk6M9toZrd1sz/VzH4b7n/dzMaF25PN7D4z+6uZrTGzL8eyzhNq8hWQM67HCQa789kLT2Ph3LH89wsbeeAN3YMhIgNPzMLCzBKBO4HLgSnAR8xsSpdmnwT2u/tpwPeB/wi3fwhIdfczgNnATYeCZMBLSISzPwc7lsK2V6M6xMz416um8c5J+fzL71by4ro9MS5SRKR/YnlmMQ/Y6O6b3b0ZeBC4skubK4H7wueLgIvMzAAHMs0sCUgHmoHBs0bpjGshI6/HCQa7k5yYwJ3XzqKsMMJn71/Oyh26B0NEBo5YhkUxsL3T6/JwW7dt3L0VOAjkEQRHHbAT2AZ8z917vtttoEnJgHk3wvqn4blv9Hkp7SFZqUncc/1ccjJSuOEXSyjfXx/bOkVEohTLsLButnXtxO+pzTygDRgDjAf+0cwmHPUBZjea2VIzW1pZOcCmzzjnFphxHbz8ffjpO2DrK1EdFtyDMZfGlmAdDN2DISIDQSzDohwY2+l1CVDRU5uwy2kEUAV8FHja3VvcfQ/wZ2BO1w9w97vdfY67z8nPz4/Bt3AcUjLgqjvhY49CWzPcezk88Y/Q2Hdv2qSC4B6MLfvquOlXS2lq7fsyXBGRWIplWCwBTjez8WaWAiwEHu/S5nHgE+HzBcALHtxssA14lwUygfnA2hjWGjsT3wU3vwbzb4YlP4cfz4f1z/Z52DkTR/GfC87ktc1V/NMi3YMhIvEVs7AIxyA+BzwDrAEecvdVZvYtM7sibPZzIM/MNgL/ABy6vPZOIAtYSRA697p796sLDQYpmXDZv8MnF0NqBH7zIXj4U1C3r9fDrppZzBffXcpjb1bwvWfXnaRiRUSOZkPlL9Y5c+b40qVL411G31qb4E+3w5/+C9Ky4fLvwrQPBjf0dcPd+cqjK3ngjW382wfO4KNnnXKSCxaRoczMlrn7Ud38XekO7pMtKRUu/DLc9Mfg5r2HPwkPLISDO7ptbmb865VTubA0n68+tpIX1+oeDBE5+RQW8VIwJeiWeve/wdt/hDvPCsY02o+eUDApMYEffXQWk4sifPY3y/lrue7BEJGTS2ERTwmJcPZn4TOvQPEseOIf4L73wb5NRzXN7HQPxsK7X+V7z6zjQH1zHIoWkeFIYTEQ5I6Hjz8GV/wIdq2En5wDL98Bba1HNBsdSePBG+dzYdlofvTiRs77jxe547n1VDfqXgwRiS0NcA80NbuC+zHW/h8UnRkESNH0o5qt3VXNHYs38PSqXWSnJXHj+RO4/tzxZKUmxaFoERmsoh3gVlgMVKsfgye+APX74B2fh/P/CZLTjmq2csdB7nhuPc+t2UNORjI3vXMiHz/7VDJSFBoi0jeFxVBQXwXPfhXe/DXknQ5X/Decena3Td/afoDbF6/npfWVjMpK4dPvnMh1808lLTnxJBctIoOJwmIo2fQC/P5WOLAN5n4KLv56cHNfN5ZtreL7izfw8sa9jI6kcvMFE1k47xSFhoh0S2Ex1DTVwovfhtd+ApmjYPYNMOdvILuo2+avbd7H7YvX88bbVRSNSOOzF57Gh+eMJSVJ1zSIyGEKi6GqfCn88T9h/TPBpbeTr4CzboKxZx11F7i788qmffzXs+tYvu0AxSPTueWi07h6VgnJiQoNEVFYDH1Vm4Ob+Jb/CpoOQuH0YA2NMxZAcvoRTd2dP27Yy+3PruOt8oOcmpfBLe86nStnjCFJoSEyrCkshovmOljxW3j9bqhcA+m5MOvjMPeTMPLIeaTcnRfW7uH2xetZVVHNhPxMbr3odN43fQyJCd3PTSUiQ5vCYrhxhy0vwxt3wdongm2l7wnONsaff0QXlbvzzKrd3PHcetbuquH00Vl8/uJJXD6tkASFhsiworAYzg5sh6U/h2X3QUMV5E+GeZ+CMxcG06WH2tudJ1fu5I7nNrBxTy2n5mXwwVklXD2rmJKcjDh+AyJysigsJFj7e+UjwdnGzrcgdQTMvA7m/S3kHl6ltq3deeKvO3ng9W28ujlYY+OciXksmF3CZdMKdYOfyBCmsJDD3GH7G0ForH4M2tvg9EuDLqqJ74KEw4Pc26vqeWT5DhYt3872qgayUpN47xlFLJhTwpxTc7Ae1t0QkcFJYSHdq94Jy+6FpfdC3R7IOy240W/GR4PFmELt7c6SLVUsWlbOE3/dSX1zG6fmZbBgVglXzy6heGR6Lx8iIoOFwkJ619oMq38Hb9wN5UsgJQtePZ4eAAAT+ElEQVSmfgCmXQ3jzofEw11PdU2tPLVyF4uWbee1zVWYdeqmmlpEeoruDhcZrBQWEr0dy+GNn8Gax6G5FjJGwZQrYOrVcOo5wc1/oe1V9Ty8vJyHl5cf0U31oTklzFY3lcigo7CQ/mtpgI3PBYPi65+GlnrIKoApVwbBMfasjvGN9nbnjbCb6smwm2pcXgYLZpfwgVnqphIZLBQWcnya64IpRVY9AhsWQ2sjZBfDlKuCrqri2R33bnTXTXXuxFEsmF3Cu6cWqptKZABTWMiJ01QD654Kzjg2PQ9tzTDiFJgaBkfRjI7gONRNtWhZOeX7g26qd5WN5uIpBVxQmk92WnKcvxkR6WxAhIWZXQb8AEgE/sfdv9NlfyrwS2A2sA+4xt23hPumA3cB2UA7MNfdG3v6LIXFSdJwANY9GQTH5hehvTW4Z2PqB4KuqoKpYNbRTfXI8nKeX7OHfXXNJCUY8yfkccmUAi6eUqCuKpEBIO5hYWaJwHrgEqAcWAJ8xN1Xd2pzMzDd3T9tZguBD7j7NWaWBCwHPubub5lZHnDA3dt6+jyFRRzUV8Ga3wddVW//EbwdRk06HByjy4Dgpr+/bNvP4jW7Wbx6N5sr6wCYUpTNJVMKuGRKAVPHZGtwXCQOBkJYnA18w93fHb7+MoC7/3unNs+EbV4NA2IXkA9cDnzU3a+L9vMUFnFWWwlrHoNVvwvmqMJh9JQgNCZdCgVndAyOb6qs5bnVu3luzW6Wbt2POxSNSOPiyUFwzJ+Qp3U3RE6SgRAWC4DL3P1vw9cfA85y9891arMybFMevt4EnAVcR9A1NZogPB509+928xk3AjcCnHLKKbO3bt0ak+9F+qlmV3Cn+MpHYPtrwbaMUTDhnTDhQph4IYwoAWBfbRMvrN3D4tW7+dOGvTS0tJGVmsQ7S/O5ZHIBF5aOZkSGxjlEYiXasIjlpD/d9Sl0Taae2iQB7wDmAvXA8+E39PwRDd3vBu6G4MziuCuWEyNSGCzIdNZNwR3jm/8QjG9sehFWPhy0yTsdJl5I3oQL+dC0d/ChOWNpbGnjzxv38tya3SxevYcnVuwkMcGYNy63o7tqbK4mOBSJh4HaDXUNwRnH9WG7rwKN7v6fPX2euqEGAXfYszoIjc0vwpY/Q2sDJCRB8ZzgjGPChVA8m3ZL5K3yAywOu6vW764FoKwwwiVTCnhX2WjOKB6hxZtEjtNA6IZKIhjgvgjYQTDA/VF3X9WpzWeBMzoNcF/t7h82sxzgeYKzi2bgaeD77v5ET5+nsBiEWptg++uHw6PiTcAhNRvGnXc4PPImsrWqnsWrgwHyJVuqaHfITElk1qk5zBuXy7zxuZw5diRpybqnQ6Q/4h4WYRHvAe4guHT2Hnf/tpl9C1jq7o+bWRrwK2AmUAUsdPfN4bHXAV8m6JZ60t3/qbfPUlgMAfVV8PZLh8PjwLZg+4ixMOGCIDzGX8B+Iry8cS9LtlTxxttVrN1VA0BKYgJnjh3B3HG5zB2fy+xTc3Rfh0gfBkRYnEwKiyHGPVhn/NBYx9t/CtYax6BoehAexXOgeBYHkvJZuvUAS7ZU8frbVazccZDWdifBYHJRNvPG5zIvDJBRWalx/sZEBhaFhQwtba1Q8ZfD4VH+RnBDIEDmaCieFUxBMmYW9fnTeXNvAq+/XcWSLVUs37afxpZ2ACbkZ3Z0W80dl0tJTrru75BhTWEhQ1tLI+xeGcyYu2MZVCyHvRvouOBu5KlBgIyZRUvhTFYxntfKm1gSBkh1YxA0RSPSOoJj3vhcTsvP0jrkMqwoLGT4aayGnW8GAVKxHHb8BQ6G4x4Y5JdB8Szai2ayNa2UP9cW8urWWpa8XcWemiYAIqlJTCqMMKkgQmlBFpMKI5QWRMhT95UMUQoLEQjuLK9Y3ilAlkP93mBfYgoUTMXHzGJf9lSWto7n1eo81u6uZ93uGg7Ut3S8TV5mShAgh4KkMIvTCyIaQJdBT2Eh0h13OLj9yPCoeBOagyuqSEqDvNPwUadTnz2R7QklrGktZGnNKFZVNrNhdw11zYenKBszIq3j7OP0guDraaOzNC27DBoKC5FotbfDvg1BcOxeGYx97F0H+7dyeNIBg5Fj8bxJ1EYmUJ5UwrrWIpbWjWZ5ZQIb99bR3BoMopvBqbkZR5yJTMzPYtyoDDJSYjlpgkj/DYTpPkQGh4QEyC8NHp21NELVJqhcFwbIemzvOiJb/8zk1gYmA1cBpOfg406nJjKRiqQS1rUVsawun1f3tPP82j20tR/+g6wwO41xozIYPyqL8Z2+js3NIDVJZyMycCksRHqSnBasz1Ew9cjt7e1QXQ6V62Hv+jBE1pO97Tmy6yopA64ESEylvXgCNZGJ7E4uYSuFrG4qYFltLs+sqqWqrrnjLRMMinPSGZeXyfhRwWPcqEwmjMqkeGS6pjWRuFM3lMiJVF/VcRbS8ahcF9yN3nk5lvQcWnMmUp1xKjuTinnbC1nVmM+SmlzW7Wujpqm1o2lyojE2J6MjQA6FyLhRmRRmp5GoS33lOGjMQmQgaW2GA1th30bYtyn8Gj6vqTiiqUeKaBk5gQPpp1CRWMymtgL+2pjP0oPZbKxq7rjBECApwSjITqM4J53ikcFjzMh0xoxMoyQneK5xEumNwkJksGiuC6Y26QiSMEyqNkH9vsPtLAEfeQpNI8ZTlXoKOxLHsL0tl81N2ayry2ZNdQo7a5qPGCMBGJmR3BEinQOlOCcIlVGZqboRcRjTALfIYJGSCYVnBI+u6qvCIAkCxPZtJK1qE2MqljCmuZa5ndsmJOP5hTRnFlGXkk9V4ih2k8u21pFsbsxmTWWE321M50DzkcGQkpTAmBFpHWFSNDKd0ZHU4JGdxuhIKqOyUrV64TCnsBAZyDJyg0dJlz/83KF2D1TvgOqK4FFTgVVXkFpdQWr1WnKrKzittYFzOx+XAO15o2lKL6A2ZTRViXns9Fy2t4xgQ90I1u7J5KnaLGo9ja5rk+VmpjA6kkp++BgdSQsD5cjn6vYamvRfVWQwMoNIQfAontV9G3doPBCGyc4gWGp2klC9g/TqnaRXV5BftYzSxgNHHpcKnpROS1oeDSm51CTlcsBGUOnZ7GqNsONAFlt3ZfJSfTq72rI5QBbO4bOOrNSko0MlO5X8rFRyM1PIyUwhL/yamZKoiRwHCYWFyFBlBuk5waPr5b+dNddDzc5OZyg7sbpKUuoqSandw4i6vZTUrYG6vUde0ZUcPNwSaU7NpSElh5rEHPYzgkofwc6aLLbvy2JLQyZvtGZR5dlUEaGRw/NspSQlkJsRBEduZjK5mankZiQfESi5GSnkZqV0tEvWZcRxobAQGe5SMiBvYvDoTXs7NOyHukqo2xN8ra3E6ipJDR8j6yoZW7suCJaWuuC4xPARaktMpSl5JA2J2dQkjuAgEfa3ZlJZlcXuPRlUNGfwZnM6+z3CfiIc8CyqyeBQt1gkLYnczJTgkZHCiIxkRqQffozs8jo7/KqbHo+PwkJEopOQAJl5wYOyvts313UEShAwldBQRWJ9FRkNVWTUV5FXXwUNO4Krvhr2g4eXBacc+VbtlkRTcjYNiSOoScjmgEXYX5dF5cFMKtsyqGxJY2NLGtVkUO2ZR3xtJpjsMT05sdsQ6Rouh/clEUlLJpKWRHqyussUFiISGymZwSNnXHTt29uD1RDrq4JHQ/i1fh8JDVWk11eRXr+P3Ib9nFpfBfUbobUK2pqDk46U7t+2NSGNxqQsGhKyqLNMapozOdiUwf6qdKra0qlsSaOiLYO1nkE1mVR7BtVkUOsZ1JBOE8kkJiQQSUsKHqnJ4fNksg9tS0vu8rXz/mBbxiAfn1FYiMjAkJBweIylry6xQ9yhpQEaD3bzOACNB0lqPEhW+MgPt9G4LfjaehASWqGXYZB2EmlKzKQxIYOGtgzq6tOprUun2tM42J7GgbZU9remssfT2UwGdZ5GLenUeDq1pFMXPm9MSCc1JZWs1CSy0pLITE0iKzWJzJRDzxN72B60z0pNJDM12JaZknTS79xXWIjI4GUWjLmkZEB2Uf+Pd4eW+qODpuFAMG19Uw0JTTWkN9WQ3lRLTlM1NAXbad5z+Dm1UX1ci6XQ2JpJQ1069fUZ1JJGradR3Z7OwfYgdGo9nX2kUUM6dZ5OHWnUeBA6taRT62nUkU5ScmoYIklMLxnBDxbO7P/33w8KCxEZvswOd5dljzn292lvh+baw+HRVNMRNocftSQ3HSS5qZZIcy001XZqtx+aavDmWqylPqqPbLUUGtvTaWjKpLJyKrDo2OuPQkzDwswuA35AcC3E/7j7d7rsTwV+CcwG9gHXuPuWTvtPAVYD33D378WyVhGRY5aQAGnZweM4GEBbaxA8HeFTC03V4evDAZPUVEtWUw1ZzbXkZxefkG+jNzELCzNLBO4ELgHKgSVm9ri7r+7U7JPAfnc/zcwWAv8BXNNp//eBp2JVo4jIgJOYBOkjg8cAEsu7W+YBG919s7s3Aw8STvPfyZXAfeHzRcBFFl4uYGZXAZuBVTGsUUREohDLsCgGtnd6XR5u67aNu7cCB4E8M8sEvgR8s7cPMLMbzWypmS2trKw8YYWLiMiRYhkW3V3X1XU+9J7afBP4vrv3eomBu9/t7nPcfU5+fv4xlikiIn2J5QB3OTC20+sSoKKHNuVmlgSMAKqAs4AFZvZdYCTQbmaN7v6jGNYrIiI9iGVYLAFON7PxwA5gIfDRLm0eBz4BvAosAF7wYDWm8w41MLNvALUKChGR+IlZWLh7q5l9DniG4NLZe9x9lZl9C1jq7o8DPwd+ZWYbCc4oFsaqHhEROXZaVlVEZBiLdllVTQwvIiJ9GjJnFmZWCWw9jrcYBew9QeXE2mCqFQZXvYOpVhhc9Q6mWmFw1Xs8tZ7q7n1eTjpkwuJ4mdnSaE7FBoLBVCsMrnoHU60wuOodTLXC4Kr3ZNSqbigREemTwkJERPqksDjs7ngX0A+DqVYYXPUOplphcNU7mGqFwVVvzGvVmIWIiPRJZxYiItInhYWIiPRp2IeFmV1mZuvMbKOZ3RbvenpjZmPN7EUzW2Nmq8zs1njX1BczSzSzv5jZ/8W7lr6Y2UgzW2Rma8Of8dnxrqknZvb34f8DK83sATNLi3dNnZnZPWa2x8xWdtqWa2aLzWxD+DUnnjUe0kOt/xn+f7DCzB41swGzElF39Xba9wUzczMbdaI/d1iHRafV/C4HpgAfMbMp8a2qV63AP7r7ZGA+8NkBXi/ArcCaeBcRpR8AT7t7GXAmA7RuMysGbgHmuPs0grnXBtq8ar8ALuuy7TbgeXc/HXg+fD0Q/IKja10MTHP36cB64Msnu6he/IKj68XMxhKsTLotFh86rMOC6FbzGzDcfae7Lw+f1xD8Mov94rvHyMxKgPcC/xPvWvpiZtnA+QSTW+Luze5+IL5V9SoJSA+n9s/g6On/48rd/0gwOWhnnVfGvA+46qQW1YPuanX3Z8MF2QBeI1hiYUDo4WcLwTLU/8TR6wadEMM9LKJZzW9AMrNxwEzg9fhW0qs7CP7nbY93IVGYAFQC94bdZv8Trtg44Lj7DuB7BH9B7gQOuvuz8a0qKgXuvhOCP3yA0XGuJ1p/AzwV7yJ6Y2ZXADvc/a1YfcZwD4toVvMbcMwsC3gY+Ly7V8e7nu6Y2fuAPe6+LN61RCkJmAX8xN1nAnUMnG6SI4R9/VcC44ExQKaZXRffqoYmM/tngu7f++NdS0/MLAP4Z+Brsfyc4R4W0azmN6CYWTJBUNzv7o/Eu55enAtcYWZbCLr33mVmv45vSb0qB8rd/dCZ2iKC8BiILgbedvdKd28BHgHOiXNN0dhtZkUA4dc9ca6nV2b2CeB9wLU+sG9Im0jwh8Nb4b+3EmC5mRWeyA8Z7mHRsZqfmaUQDBI+HueaemRmRtCnvsbdb493Pb1x9y+7e4m7jyP4ub7g7gP2r1933wVsN7PScNNFwOo4ltSbbcB8M8sI/5+4iAE6GN/FoZUxCb8+FsdaemVmlwFfAq5w9/p419Mbd/+ru49293Hhv7dyYFb4//QJM6zDIhzAOrSa3xrgIXdfFd+qenUu8DGCv9LfDB/viXdRQ8jfAfeb2QpgBvBvca6nW+HZzyJgOfBXgn/HA2pqCjN7gGC55FIzKzezTwLfAS4xsw0EV+18J541HtJDrT8CIsDi8N/ZT+NaZCc91Bv7zx3YZ1ciIjIQDOszCxERiY7CQkRE+qSwEBGRPiksRESkTwoLERHpk8JCZAAwswsGw8y8MnwpLEREpE8KC5F+MLPrzOyN8Eatu8L1OmrN7L/MbLmZPW9m+WHbGWb2Wqc1EXLC7aeZ2XNm9lZ4zMTw7bM6radxf3h3tsiAoLAQiZKZTQauAc519xlAG3AtkAksd/dZwEvA18NDfgl8KVwT4a+dtt8P3OnuZxLM6bQz3D4T+DzB2ioTCO7YFxkQkuJdgMggchEwG1gS/tGfTjAZXjvw27DNr4FHzGwEMNLdXwq33wf8r5lFgGJ3fxTA3RsBwvd7w93Lw9dvAuOAl2P/bYn0TWEhEj0D7nP3I1ZNM7OvdmnX2xw6vXUtNXV63ob+fcoAom4okeg9Dywws9HQsab0qQT/jhaEbT4KvOzuB4H9ZnZeuP1jwEvh+iPlZnZV+B6p4XoEIgOa/nIRiZK7rzazfwGeNbMEoAX4LMFCSVPNbBlwkGBcA4JpuH8ahsFm4IZw+8eAu8zsW+F7fOgkfhsix0SzzoocJzOrdfeseNchEkvqhhIRkT7pzEJERPqkMwsREemTwkJERPqksBARkT4pLEREpE8KCxER6dP/B84DaRbRd+HQAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "print(history.history.keys())\n",
    "\n",
    "plt.plot(history.history['loss'])\n",
    "plt.plot(history.history['val_loss'])\n",
    "plt.title('model loss')\n",
    "plt.ylabel('loss')\n",
    "plt.xlabel('epoch')\n",
    "plt.legend(['train', 'validation'], loc='upper right')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.去噪自编码器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 读取数据集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 176,
   "metadata": {},
   "outputs": [],
   "source": [
    "(X_train, _), (X_test, _) = mnist.load_data()\n",
    "\n",
    "X_train = X_train.reshape(X_train.shape[0], 28, 28, 1)\n",
    "X_test = X_test.reshape(X_test.shape[0], 28, 28, 1)\n",
    "\n",
    "X_train = X_train.astype(\"float32\")/255.\n",
    "X_test = X_test.astype(\"float32\")/255."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 加噪"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 177,
   "metadata": {},
   "outputs": [],
   "source": [
    "noise_factor = 0.5\n",
    "X_train_noisy = X_train + noise_factor * np.random.normal(loc=0.0, scale=1.0, size=X_train.shape) \n",
    "X_test_noisy = X_test + noise_factor * np.random.normal(loc=0.0, scale=1.0, size=X_test.shape) \n",
    "\n",
    "X_train_noisy = np.clip(X_train_noisy, 0., 1.)\n",
    "X_test_noisy = np.clip(X_test_noisy, 0., 1.)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 去噪自编码器建模"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 178,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = Input(shape=(28, 28, 1))\n",
    "\n",
    "# 编码器\n",
    "conv1_1 = Conv2D(32, (3, 3), activation='relu', padding='same')(x)\n",
    "pool1 = MaxPooling2D((2, 2), padding='same')(conv1_1)\n",
    "conv1_2 = Conv2D(32, (3, 3), activation='relu', padding='same')(pool1)\n",
    "h = MaxPooling2D((2, 2), padding='same')(conv1_2)\n",
    "\n",
    "\n",
    "# 解码器\n",
    "conv2_1 = Conv2D(32, (3, 3), activation='relu', padding='same')(h)\n",
    "up1 = UpSampling2D((2, 2))(conv2_1)\n",
    "conv2_2 = Conv2D(32, (3, 3), activation='relu', padding='same')(up1)\n",
    "up2 = UpSampling2D((2, 2))(conv2_2)\n",
    "r = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(up2)\n",
    "\n",
    "autoencoder = Model(inputs=x, outputs=r)\n",
    "autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 模型可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 179,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<svg height=\"702pt\" viewBox=\"0.00 0.00 275.00 702.00\" width=\"275pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g class=\"graph\" id=\"graph0\" transform=\"scale(1 1) rotate(0) translate(4 698)\">\n",
       "<title>G</title>\n",
       "<polygon fill=\"white\" points=\"-4,4 -4,-698 271,-698 271,4 -4,4\" stroke=\"none\"/>\n",
       "<!-- 140641014501504 -->\n",
       "<g class=\"node\" id=\"node1\"><title>140641014501504</title>\n",
       "<polygon fill=\"none\" points=\"49,-657.5 49,-693.5 218,-693.5 218,-657.5 49,-657.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-671.8\">input_32: InputLayer</text>\n",
       "</g>\n",
       "<!-- 140641014501616 -->\n",
       "<g class=\"node\" id=\"node2\"><title>140641014501616</title>\n",
       "<polygon fill=\"none\" points=\"53.5,-584.5 53.5,-620.5 213.5,-620.5 213.5,-584.5 53.5,-584.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-598.8\">conv2d_27: Conv2D</text>\n",
       "</g>\n",
       "<!-- 140641014501504&#45;&gt;140641014501616 -->\n",
       "<g class=\"edge\" id=\"edge1\"><title>140641014501504-&gt;140641014501616</title>\n",
       "<path d=\"M133.5,-657.313C133.5,-649.289 133.5,-639.547 133.5,-630.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"137,-630.529 133.5,-620.529 130,-630.529 137,-630.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641014575232 -->\n",
       "<g class=\"node\" id=\"node3\"><title>140641014575232</title>\n",
       "<polygon fill=\"none\" points=\"2,-511.5 2,-547.5 265,-547.5 265,-511.5 2,-511.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-525.8\">max_pooling2d_12: MaxPooling2D</text>\n",
       "</g>\n",
       "<!-- 140641014501616&#45;&gt;140641014575232 -->\n",
       "<g class=\"edge\" id=\"edge2\"><title>140641014501616-&gt;140641014575232</title>\n",
       "<path d=\"M133.5,-584.313C133.5,-576.289 133.5,-566.547 133.5,-557.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"137,-557.529 133.5,-547.529 130,-557.529 137,-557.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641014575736 -->\n",
       "<g class=\"node\" id=\"node4\"><title>140641014575736</title>\n",
       "<polygon fill=\"none\" points=\"53.5,-438.5 53.5,-474.5 213.5,-474.5 213.5,-438.5 53.5,-438.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-452.8\">conv2d_28: Conv2D</text>\n",
       "</g>\n",
       "<!-- 140641014575232&#45;&gt;140641014575736 -->\n",
       "<g class=\"edge\" id=\"edge3\"><title>140641014575232-&gt;140641014575736</title>\n",
       "<path d=\"M133.5,-511.313C133.5,-503.289 133.5,-493.547 133.5,-484.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"137,-484.529 133.5,-474.529 130,-484.529 137,-484.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641014578144 -->\n",
       "<g class=\"node\" id=\"node5\"><title>140641014578144</title>\n",
       "<polygon fill=\"none\" points=\"2,-365.5 2,-401.5 265,-401.5 265,-365.5 2,-365.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-379.8\">max_pooling2d_13: MaxPooling2D</text>\n",
       "</g>\n",
       "<!-- 140641014575736&#45;&gt;140641014578144 -->\n",
       "<g class=\"edge\" id=\"edge4\"><title>140641014575736-&gt;140641014578144</title>\n",
       "<path d=\"M133.5,-438.313C133.5,-430.289 133.5,-420.547 133.5,-411.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"137,-411.529 133.5,-401.529 130,-411.529 137,-411.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641014134600 -->\n",
       "<g class=\"node\" id=\"node6\"><title>140641014134600</title>\n",
       "<polygon fill=\"none\" points=\"53.5,-292.5 53.5,-328.5 213.5,-328.5 213.5,-292.5 53.5,-292.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-306.8\">conv2d_29: Conv2D</text>\n",
       "</g>\n",
       "<!-- 140641014578144&#45;&gt;140641014134600 -->\n",
       "<g class=\"edge\" id=\"edge5\"><title>140641014578144-&gt;140641014134600</title>\n",
       "<path d=\"M133.5,-365.313C133.5,-357.289 133.5,-347.547 133.5,-338.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"137,-338.529 133.5,-328.529 130,-338.529 137,-338.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641014134544 -->\n",
       "<g class=\"node\" id=\"node7\"><title>140641014134544</title>\n",
       "<polygon fill=\"none\" points=\"0,-219.5 0,-255.5 267,-255.5 267,-219.5 0,-219.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-233.8\">up_sampling2d_12: UpSampling2D</text>\n",
       "</g>\n",
       "<!-- 140641014134600&#45;&gt;140641014134544 -->\n",
       "<g class=\"edge\" id=\"edge6\"><title>140641014134600-&gt;140641014134544</title>\n",
       "<path d=\"M133.5,-292.313C133.5,-284.289 133.5,-274.547 133.5,-265.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"137,-265.529 133.5,-255.529 130,-265.529 137,-265.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641014230096 -->\n",
       "<g class=\"node\" id=\"node8\"><title>140641014230096</title>\n",
       "<polygon fill=\"none\" points=\"53.5,-146.5 53.5,-182.5 213.5,-182.5 213.5,-146.5 53.5,-146.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-160.8\">conv2d_30: Conv2D</text>\n",
       "</g>\n",
       "<!-- 140641014134544&#45;&gt;140641014230096 -->\n",
       "<g class=\"edge\" id=\"edge7\"><title>140641014134544-&gt;140641014230096</title>\n",
       "<path d=\"M133.5,-219.313C133.5,-211.289 133.5,-201.547 133.5,-192.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"137,-192.529 133.5,-182.529 130,-192.529 137,-192.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641014337944 -->\n",
       "<g class=\"node\" id=\"node9\"><title>140641014337944</title>\n",
       "<polygon fill=\"none\" points=\"0,-73.5 0,-109.5 267,-109.5 267,-73.5 0,-73.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-87.8\">up_sampling2d_13: UpSampling2D</text>\n",
       "</g>\n",
       "<!-- 140641014230096&#45;&gt;140641014337944 -->\n",
       "<g class=\"edge\" id=\"edge8\"><title>140641014230096-&gt;140641014337944</title>\n",
       "<path d=\"M133.5,-146.313C133.5,-138.289 133.5,-128.547 133.5,-119.569\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"137,-119.529 133.5,-109.529 130,-119.529 137,-119.529\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- 140641013907072 -->\n",
       "<g class=\"node\" id=\"node10\"><title>140641013907072</title>\n",
       "<polygon fill=\"none\" points=\"53.5,-0.5 53.5,-36.5 213.5,-36.5 213.5,-0.5 53.5,-0.5\" stroke=\"black\"/>\n",
       "<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"133.5\" y=\"-14.8\">conv2d_31: Conv2D</text>\n",
       "</g>\n",
       "<!-- 140641014337944&#45;&gt;140641013907072 -->\n",
       "<g class=\"edge\" id=\"edge9\"><title>140641014337944-&gt;140641013907072</title>\n",
       "<path d=\"M133.5,-73.3129C133.5,-65.2895 133.5,-55.5475 133.5,-46.5691\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"137,-46.5288 133.5,-36.5288 130,-46.5289 137,-46.5288\" stroke=\"black\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>"
      ],
      "text/plain": [
       "<IPython.core.display.SVG object>"
      ]
     },
     "execution_count": 179,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from IPython.display import SVG\n",
    "from keras.utils.vis_utils import model_to_dot\n",
    "\n",
    "SVG(model_to_dot(autoencoder).create(prog='dot', format='svg'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 180,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 60000 samples, validate on 10000 samples\n",
      "Epoch 1/3\n",
      "60000/60000 [==============================] - 65s 1ms/step - loss: 0.1772 - val_loss: 0.1247\n",
      "Epoch 2/3\n",
      "60000/60000 [==============================] - 62s 1ms/step - loss: 0.1205 - val_loss: 0.1128\n",
      "Epoch 3/3\n",
      "60000/60000 [==============================] - 63s 1ms/step - loss: 0.1126 - val_loss: 0.1120\n"
     ]
    }
   ],
   "source": [
    "epochs = 3\n",
    "batch_size = 128\n",
    "\n",
    "history = autoencoder.fit(X_train_noisy, X_train, \n",
    "                          batch_size=batch_size,\n",
    "                          epochs=epochs, verbose=1,\n",
    "                          validation_data=(X_test_noisy, X_test))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 查看解码效果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 181,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABHEAAADnCAYAAACZmMoMAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzsnWegFeX19RdIFSwgRQUsiL13jQU0xoItaiwoscWuUd9YY9eIErtYYjfYSyzYidHYsIEdUeyIYgGxIYIo5/3gfx7WXpcZ5l7PveTg+n3ah2funDkz85QZ9tqrWaVSgTHGGGOMMcYYY4z536b57D4AY4wxxhhjjDHGGDNr/BLHGGOMMcYYY4wxpgbwSxxjjDHGGGOMMcaYGsAvcYwxxhhjjDHGGGNqAL/EMcYYY4wxxhhjjKkB/BLHGGOMMcYYY4wxpgbwSxxjjDHGGGOMMcaYGsAvcYwxxhhjjDHGGGNqAL/EMcYYY4wxxhhjjKkB/BLHGGOMMcYYY4wxpgZoUZ+N55tvvkqXLl2yOLS99dZbKW7fvn1o++STT1K8/PLLp/j111/P/a6WLVuGz9OnT0/xTz/9lOJWrVqF7X744YcUd+3aNcWfffZZ2G6eeeZJcdu2bUPb559/nuLWrVuneOrUqWG7eeedN8UtWsRTOXHiRMyMjh07ltpOqVQqzUptOAvat29fWWCBBQDE6wIASy65ZIonTZoU2vhz2WMu+q3ZMQDAggsuGLYbP358ivlaKHwN+f5QevTokeLJkyeHtg8//DD37xj+Lfr7+X5v165daJP7bkKlUulc6gtnQbNmzSpZ3L1799D20Ucf5f5d584zvv67775LsZ4XplOnTuHzV199leKllloqxaNGjcrdxyKLLJJiPecLL7xwinXs4HGF++lCCy0Utnvvvfdyv5vh4502bVpo4/7N5wYA5pprLgA/94OpU6dWpS+2bNmy0qZNGwDA3HPPHdr4vudzB8R7is8JXxcgntdx48Y16Bj5ftZzwvB107GjGvA4z2O8zhN6TRnedtq0aY3SF7X/8znTe5bHX77GPOcAwNtvv13qOLifTpgwIXe77J4D6s6f33zzTe7f8Tg6duzYFPM8CMTrU3b/Ogd///33KV588cVD2xdffJG2+eGHH6rSFzt16lRZbLHFAAAvvPBCNXYZ4HOkayc+lx06dEjxl19+Gbbr1q1binkcf/nll0sfB49/PLYWsfrqq4fPfH543NI5hOd1HZumTJnCHxulLxahfUzXdhl6rb7++uvcffIakPffvHn8v1Ju+/bbb3OPgcdUHXsrlcpMtysae5s1i12F1w28ZuB9A/E66jXm/lytNWrZa6isssoqKX711VdztytaK+Yx//zzh896P2foWjZbNwDAxx9/nLt/Xg/rOeaxkOd0IM4p/Dwl/Sv0YR3f+L798ccfq9YXmzdvXsn2XTQvz2IfKV522WVDG/9eHteAOAdxv9JnHoafF/XZ5YMPPkixXoN33303d59M0bMk3198b9VnfcNUqy+2aNGiks3hfI8CcSzkcUzhMVTHT16L6D2bBz+nAnF9xPe5fhePjXoeszWFHi/Ps0AcO8o+c/C6CYjz/corrxzaRo8eneIpU6aU6ov1eonTpUsXnH/++QCArbbaKrT97ne/S/H6668f2k455ZQU33bbbSnmFzoKdyggXgC+yXVhPGbMmBT3798/xeeee27Ybu21107xcsstF9oGDRqUYr4A77zzTthunXXWSbFe7BtvvBEzY8sttwyfr7/++plu11gssMACOOaYYwAAZ5xxRmi75ZZbUvz000+HtqeeeirFN9xwQ6nv2myzzcLnm2++OcV8//z1r38N2/3jH/9I8YUXXpi7/zXWWCPFOvHx5MnXXif3/fffP3f/DP8W/h1AXDysu+66oe3ss8/mj2PQCPy///f/wucjjjgid9sddtghxcOHD09x0YPL9ttvHz7feeedKeZzoQMSc+yxx6b4oIMOCm0HHnhgin/zm9+Ett/+9rcp5sH7uOOOC9vtsssuud/NXH755SnWFxs8GfO5AWYslIcOHVrqe8rQpk0brLbaagDqPihl4ywQzx0AnHfeeSleYYUVUnz33XeH7fi8nnjiiQ06xhVXXDHFzz77bO523Ad4rKgW/MDBk6eOu0Uvq3hO+eijjxqlL/L1AIDnnnsuxTrW8LzI17hnz55hu80337zUd//+979P8VVXXZW7XfayQmMAeOihh3L/7uijj07xn//85xTzPAjEa6ALGN4/PyzqIvyVV15J8WmnnRbasjmz6H6sL4stthhGjBgBoO7DbjXgc7T11luHNj6Xm266aYpvvfXWsN0hhxyS4gMOOCDF/OJnVvD4t9FGG5X6m+y8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fl04E8cYY4wxxhhjjDGmBvBLHGOMMcYYY4wxxpgawHIqU1U47XCDDTYIbSeddFKKOeWb04uBKIXiVNVNNtkkbMdyKk1xLJIAmaaHrwfLp4CYSrrkkkuGNpbCvfPOOym2TKNxUOtw7mM77LBDikeMGBG2+/e//51ip/POHjhFe9lllw1tbHP88ssvp5gtjoEoqyiSLPJ3LbbYYqGNx+wPPvggtP3www+5+zTlKZKzsaxntdVWC229e/dOMV/7Bx98MGz37bffVuU452TUOvy0005L8VZbbZXiTz/9NGx32223pbjasmCVaey5554p3m677ULb2WefneInn3wyxe6jP8N9bN55583djqWHlnnXLkXXe9ttt03xHnvsEdoWWWSRFPPah0tBAECrVq1mGuv3derUKcUq1XvzzTdTfOWVV4Y233u/TpyJY4wxxhhjjDHGGFMD+CWOMcYYY4wxxhhjTA0wW+VUmgbM1fNVcjF16tQUT5kyJcUNrQzPsgGVEHCqG6cmawocOzqou8OvtWI9u18cdNBBoa1jx44pfu6551J85513hu0+//zzFHPld/57ANhll11m+r1AvFacJumUw/pTjXPG10Cv1dprr53iZZZZJrQ99NBDv/i7TTE8DqsM55xzzkkxS9023XTTsB3LGVWawenmv9ZxsbHga8eOOLvttlvY7pNPPkkxSxS//PLLsF1Zlxqen/v06RPaWB551VVXhTb+bo/FDYfPnUqHO3TokGJ2hASA9ddfP8VPP/10ir///vvc/ZsZ8Nw1aNCg0LbFFlvM9G/uueee8PmNN95IcbXnVpZiAMCf/vSnFC+99NKhjcdwXo9ZTvUzfK332Wef0MbnnMc4ldC4HzUefA30GY4/83bqmMvXePXVV0/xIYccErZbb731UqxSq7LPF7z20XmWP3Oszr28Hs6TQvue+5mikhr67oHvF75OtVC2wZk4xhhjjDHGGGOMMTWAX+IYY4wxxhhjjDHG1AB+iWOMMcYYY4wxxhhTA8zWmjha42T77bdP8YYbbhjaJk6cmGK2t2W7VCDWzmG9Y+fOncN2q6yySopZw6+fWV/ItR0A4OGHH07x0KFDQxvXGvg1aRS5Fg3XtgGAF198McWs7dR6QmzTV3TuWNfI9ZSAutpXM3thfapas2622WYpVr3x/fff37gH9iuFa5qwjfiAAQPCdqwT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1HqGRosWLUI/bcvngWjpTi2NvMcee4R++j7ytaRn82iOrP43ZjG3OZ+XU+0l6jWPuGvXrqGtffv2HuvYT58+PfTL+eZomHxt6zqW87G1LOYpp5ziseYXm5ntuuuuHut1n/OS9TrIefp6tsPUqVM9vueee0K/devWGcqfnZDP1dra/O08VprTv379+pL/Vi2fxVBp+myiZ0udffbZoZ/e43788UePtRSyWbxvobJ0ncvPC6XWx/y8oGdq9O7du2Q/PZNFz3PAtqFrXLkz2hq6ButraknrBQsWhH56vey8886hTe/rtXyOXDn6/PHyyy+HNv2eMGjQII/333//0E/X5datW4c2XW9Hjx7tcS5TjobT9XTw4MGh7eGHH/ZYxymXpL/77rs9fuqpp0Jbke+Z7MQBAAAAAAAoAH7EAQAAAAAAKIDCp1Plcm9DhgzxWLfK5ZSNoUOHerx27dpGene1R7d857KYur1NtyLn0tQdOnSo9/VyOpVuH83b+7XcrsY5rUTTnXKqgqZ+6Jb1efPmhX5aIlv/LbPilavbUjomF154YWjTLZC6NXzEiBGhH+mLlbFx48bw5w8//NBjLTduFtMeNWUql2XU8qabS7cvm5l99dVXHt966631/r0ZKTqlbMs1RNfbclv3dQ3M6yY2pWk4mc6xQw891ONOnTqFfvr5f/311x4vW7Ys9Kv2e05TKlfWWNcvvfflsddU1o4dO5bspylU+RlJn5+KnApQFI0xp/Q1NY01p5urfGyApmI2pOx5rclpidOmTfN4wIABHh944IGhn37PzEdz6LEOzz77rMeUFN86uh7qvfC+++4L/UqlUN1///2h37333ltvv6JjJw4AAAAAAEAB8CMOAAAAAABAAfAjDgAAAAAAQAEU/kwczYczMzvqqKM81rzQXFpOS0GTP1o5y5cv9/imm24q2U/zx/PZC/vtt5/Hhx9+uMddunQJ/TTnNJfy1jMDvv32W4+1NGv+71auXBna9Kwkzuv4h+aqahnxXJZRP78HHnjA4zlz5oR++tkyFxsun+11yy23eDx27NjQ1q9fP48HDhzosZ4jZma24447eqxnUOV8b/3ze++9F9oeffRRj+fPn+8xc6r50bOT8tlG3333ncfDhw/3OJ8Dhi2j54oddthhHuezF7Tk+2effeZxPlNM12fW08aTSzqXO6NP6Xk2ev/M55btvvvuHnfr1i206XmDGzZsKPmeVL4WuDaaln7+OoZLly4N/fQ6yNeInr2kr8e9tX55fixatMjj119/3WM9l9MsnhuYz1PRswd/+OGHirxPxPuinqXYpk2b0E/HVL/n33777aHf5p6Do/fPcuew5rPImmo9ZScOAAAAAABAAfAjDgAAAAAAQAEUMp1Ktxmffvrpoa1du3Yeazm5xx9/PPRju2Hj0C34M2fObNBr6HY23XqsW0ezPJ667U1jthRvPR0fTaWoq6sL/datW+fxpEmTPKakeOPIW4W19OUnn3wS2r744guPP/roI4979uwZ+rVu3dpj3fKtJVHNYrnwPO81ZZH51rzkNbVHjx4e//LLL6Ft3LhxHi9cuNBjxvTf6WeUS0lrKuKsWbM8Hj9+fOin27dHjRrlcU5nYzyano5B3sav46Wlw7XUvFlMbe3atWto09QPfc7l+aaY9N5dLj1S05vNYulrfQbOzwJcB/XbuHGjx2PGjPH4jz/+CP0OOOAAj1etWhXadC2uptLV21q+L2pZcf2en9OMFy9e7PG1117rcUO/Z+gzUV53da3VYzq25t/bWuzEAQAAAAAAKAB+xAEAAAAAACiAQqZT6bbTc845J7TpadK6zUora2DbaOgWTv3vylXEQdPQMfn55589HjlyZOin2//LVc1A48ufv1a6eeedd+qNy2F7dnXQdDmzuH1YK+CYmU2cONFjKlI1XJ47+lnOnTvX4wULFoR+Ood12z5ra/OWx+f777/3eMSIER4ff/zxoZ9eC6NHjw5tmtKh91nW5eLQsSpXaVWvn+23377ka2zO3yPSz1Yr6z7xxBOhX7mKf7lKERomp0l1797dY00bzKluWgV5xYoVW/0+dHzz2JarTtVU2IkDAAAAAABQAPyIAwAAAAAAUAD8iAMAAAAAAFAAhTwTR8vsdejQIbRpWV0tGaelwQBURnPJC0XDkT9fWzS/f7vttgtteg6OnilnZrZkyRKPOYelckrl4LO2Vid9Fq2rq/P4mWeeCf20/HEuXcyaXV10ruu4m8Wx1zM/83/HNbF1yp2FgsaXr99169Z5vHLlSo/nzJkT+o0bN66i7+Pvv//2OJ9Lp23N5RphJw4AAAAAAEAB8CMOAAAAAABAARQynUq3Xb311luhTUvnPvbYYx7rNigAAGqR3j9Xr14d2l588UWP//zzz9CmpbDZug80jM4dTf9HbdHrQOOcqqrlx/OaXOr1gKLJ1/2UKVM8HjZsmMezZ88O/crNiYbQeVTp124M7MQBAAAAAAAoAH7EAQAAAAAAKAB+xAEAAAAAACiAwpyJU6os6ogRI0I/PRMnl+oDAAD/J+ehb9iwoWQbZcUBoOnkc2/0exFQTX7//XePp02b5nERzqnZltiJAwAAAAAAUAD8iAMAAAAAAFAAW5pOtcbMljbGG/k3uo1w7dq19cZVbN8KvlaTjSEYxyrAGFYHxtFi+doCYgyrA+NYfIzhNpDTqRqhrDjjWHxVMYZ//fVXvXEN2axx/J9GWAQAAAAAAABQYaRTAQAAAAAAFAA/4gAAAAAAABQAP+IAAAAAAAAUAD/iAAAAAAAAFAA/4gAAAAAAABQAP+IAAAAAAAAUAD/iAAAAAAAAFAA/4gAAAAAAABQAP+IAAAAAAAAUwP8CQYrbCig0MzkAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 1440x432 with 20 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "decoded_imgs = autoencoder.predict(X_test_noisy)\n",
    "\n",
    "n = 10\n",
    "plt.figure(figsize=(20, 6))\n",
    "for i in range(n):\n",
    "    # 原图\n",
    "    ax = plt.subplot(3, n, i+1)\n",
    "    plt.imshow(X_test_noisy[i].reshape(28, 28))\n",
    "    plt.gray()\n",
    "    ax.get_xaxis().set_visible(False)\n",
    "    ax.get_yaxis().set_visible(False)\n",
    "\n",
    "    \n",
    "    # 解码效果图\n",
    "    ax = plt.subplot(3, n, i+n+1)\n",
    "    plt.imshow(decoded_imgs[i].reshape(28, 28))\n",
    "    plt.gray()\n",
    "    ax.get_xaxis().set_visible(False)\n",
    "    ax.get_yaxis().set_visible(False)\n",
    "    \n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练过程可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 182,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dict_keys(['val_loss', 'loss'])\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "print(history.history.keys())\n",
    "\n",
    "plt.plot(history.history['loss'])\n",
    "plt.plot(history.history['val_loss'])\n",
    "plt.title('model loss')\n",
    "plt.ylabel('loss')\n",
    "plt.xlabel('epoch')\n",
    "plt.legend(['train', 'validation'], loc='upper right')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
